Hbase模糊查询优化 - 并发查询

HBase模糊查询优化 - 并发查询

HBase查询优化续集,继上次优化后查询速度还是很慢,
这次优化我们使用并发查询,查询HBase库里的各region拆分情况,然后对查询的rowkey切分成多段,每一段单独去不同的region中查询,使我们可以并发查询来提升查询速度。

优化后经过测试查询速度大大提升!

代码如下

package query;import main.TaskExecutors;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.util.Bytes;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;/*** <p>* 用来作为并发查询HBase使用,原理是使用scan来设置startrow和endrow。* 因为HBase存储rowkey是字典序排序;* 所以如果是单线程查询我们一般设置startrow为rowkey+"0" , endrow为rowkey+"z"。* 我们并发scan可以将startrow和endrow拆分成多份,例如:* 分为rowkey+'0' -> rowkey+'9' 和 rowkey+'A' -> rowkey+'Z' 和 rowkey+'a' -> rowkey+'z',这样就可以分为三个线程并发查询* <p/>** @author chun* @date 2022/7/21 16:48*/public class ConcurrentScanHBase {private ExecutorService pool = null;private String rowKey;//Pair自定了,也可以使用javafx.util.Pair,需要看服务器上的jdk是oracle还是openjdk,openjdk没有,可以把oracleJDK的Pair类直接复制过来使用private List<Pair<Character, Character>> rowkeyRanges;private List<Scan> scanList = new ArrayList<>();private SetScan setScan = null;private CountDownLatch countDownLatch;private static final String format = "yyyyMMddHH";public ConcurrentScanHBase(ExecutorService pool, String rowkey, List<Pair<Character, Character>> rowkeyRanges, SetScan setScan) {if (setScan == null) {throw new NullPointerException("SetScan is NULL");}this.pool = pool;this.rowKey = rowkey;this.rowkeyRanges = rowkeyRanges;this.setScan = setScan;init();}private void init() {for (Pair<Character, Character> rowkeyRange : rowkeyRanges) {scanList.add(getScann(rowKey.getBytes(), (rowKey + rowkeyRange.getKey()).getBytes(), (rowKey + rowkeyRange.getValue()).getBytes()));}countDownLatch = new CountDownLatch(rowkeyRanges.size());}//如果需要主线程等待此次任务结束,调用await()方法;public void await() {try {this.countDownLatch.await();} catch (InterruptedException e) {throw new RuntimeException(e);}}public void exec(ExecScan execScan) {for (Scan scan : scanList) {pool.execute(() -> {execScan.exec(scan);countDownLatch.countDown();});}}//只设置startrow和endrow,其他设置需要返回后自己设置private Scan getScann(byte[] rowkey, byte[] startRow, byte[] endRow) {Scan scan = new Scan();scan.withStartRow(startRow);scan.withStopRow(endRow);PrefixFilter prefixFilter = new PrefixFilter(rowkey);scan.setFilter(prefixFilter);setScan.initScan(scan);return scan;}
}

匿名内部类接口

package query;import org.apache.hadoop.hbase.client.Scan;/*** 作为执行扫描表的接口使用* 通过设置匿名内部类,来加载扫描表的实现过程** @author chun* @date 2022/7/21 17:52*/
public interface ExecScan {public void exec(Scan scan);
}
package query;import org.apache.hadoop.hbase.client.Scan;/*** 作为ConcurrentScanHBase中init方法的参数接口* 为了方便每个调用者对Scan的初始化而设计* 调用者可以通过匿名内部类的方式使用* 来设置除了startrow和endrow之外的其他参数** @author chun* @date 2022/7/21 17:52*/
public interface SetScan {public void initScan(Scan scan);
}

Pair类

package query;import javafx.beans.NamedArg;import java.io.Serializable;/*** @author chun* @date 2022/7/22 10:10*/
public class Pair<K, V> implements Serializable {/*** Key of this <code>Pair</code>.*/private K key;/*** Gets the key for this pair.** @return key for this pair*/public K getKey() {return key;}/*** Value of this this <code>Pair</code>.*/private V value;/*** Gets the value for this pair.** @return value for this pair*/public V getValue() {return value;}/*** Creates a new pair** @param key   The key for this pair* @param value The value to use for this pair*/public Pair(@NamedArg("key") K key, @NamedArg("value") V value) {this.key = key;this.value = value;}/*** <p><code>String</code> representation of this* <code>Pair</code>.</p>** <p>The default name/value delimiter '=' is always used.</p>** @return <code>String</code> representation of this <code>Pair</code>*/@Overridepublic String toString() {return key + "=" + value;}/*** <p>Generate a hash code for this <code>Pair</code>.</p>** <p>The hash code is calculated using both the name and* the value of the <code>Pair</code>.</p>** @return hash code for this <code>Pair</code>*/@Overridepublic int hashCode() {// name's hashCode is multiplied by an arbitrary prime number (13)// in order to make sure there is a difference in the hashCode between// these two parameters://  name: a  value: aa//  name: aa value: areturn key.hashCode() * 13 + (value == null ? 0 : value.hashCode());}/*** <p>Test this <code>Pair</code> for equality with another* <code>Object</code>.</p>** <p>If the <code>Object</code> to be tested is not a* <code>Pair</code> or is <code>null</code>, then this method* returns <code>false</code>.</p>** <p>Two <code>Pair</code>s are considered equal if and only if* both the names and values are equal.</p>** @param o the <code>Object</code> to test for*          equality with this <code>Pair</code>* @return <code>true</code> if the given <code>Object</code> is* equal to this <code>Pair</code> else <code>false</code>*/@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o instanceof Pair) {Pair pair = (Pair) o;if (key != null ? !key.equals(pair.key) : pair.key != null) return false;if (value != null ? !value.equals(pair.value) : pair.value != null) return false;return true;}return false;}
}

使用

public static void main(String[] args) {ArrayList<Pair<Character, Character>> pairs = new ArrayList<>();pairs.add(new Pair<>('-', '3'));pairs.add(new Pair<>('4', '9'));pairs.add(new Pair<>('A', 'J'));pairs.add(new Pair<>('K', 'T'));pairs.add(new Pair<>('U', 'Z'));pairs.add(new Pair<>('a', 'j'));pairs.add(new Pair<>('k', 't'));pairs.add(new Pair<>('u', 'z'));ConcurrentScanHBase concurrentScanHBase = new ConcurrentScanHBase(TaskExecutors.getPool(), "baidu.com", pairs, new SetScan() {@Overridepublic void initScan(Scan scan) {scan.setCacheBlocks(false);scan.setBatch(6000);scan.addFamily(Bytes.toBytes("D"));}});concurrentScanHBase.exec(new ExecScan() {@Overridepublic void exec(Scan scan) {try (Table table = HBaseHelper.getConnection().getTable(TableName.valueOf(HBaseHelper.TABLE_NAME));ResultScanner scanner = table.getScanner(scan)) {int index = 0;for (Result[] results = scanner.next(6000); results.length != 0 && index++ < 3; results = scanner.next(6000)) {for (Result result : results) {for (Cell cell : result.rawCells()) {try {byte[] bytes = Bytes.copy(cell.getValueArray(), cell.getValueOffset(),cell.getValueLength());System.out.println(bytes);} catch (Exception e) {e.printStackTrace();}}}}} catch (IOException e) {e.printStackTrace();}}});try {concurrentScanHBase.await();} catch (RuntimeException e) {e.printStackTrace();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt: 找不到Qt5Widgets.lib

在静态编译的时候&#xff0c;提示错误&#xff1a; error: dependent ‘D:\IDE\Qt\5.4.2-mingw32-rel-static\5.4.2-mingw32-rel-static\lib\Qt5Widgets.lib 去目录下看了下&#xff0c;全部是libxxxxx.a文件&#xff0c;是linux的库文件。但是之前编译是正常的&#xff0c;这…

python3读写excel文件_python3 循环读取excel文件并写入json操作

文件内容&#xff1a;excel内容&#xff1a;代码&#xff1a; import xlrd import json import operator def read_xlsx(filename): # 打开excel文件 data1 xlrd.open_workbook(filename) # 读取第一个工作表 table data1.sheets()[0] # 统计行数 n_rows table.nrows data …

Qt:error LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1600”不匹配值“1800

Visual Studio 2013生成Qt项目时报错。网上搜说是更改平台工具集&#xff0c;试了没用。退一步说我就是需要使用vs2013&#xff0c;改成其他的会不符合项目需求。于是打开了项目文件.sln&#xff0c;如下&#xff1a; 才发现目标工程的Qt版本是5.7.0&#xff0c;vs2013里面设置…

JAVA程序绑定到指定的CPU核上

由于服务器上某几个核被C程序绑定了&#xff0c;我们的java程序有的线程会使用到&#xff0c;导致C程序丢包异常&#xff0c;所以需要将JAVA程序绑定到指定的CPU核上 1.命令介绍 1.taskset命令 taskset -c <cpu核编号> <pid> #可以指定进程绑定到哪个cpu核上2.t…

【转】URN_URI_URL详解

URI&#xff0c;Uniform Resource Identifier&#xff0c;统一资源标识符。 URN&#xff0c;Uniform Resource Name&#xff0c;统一资源命名 URL&#xff0c;Uniform Resource Location&#xff0c;统一资源定位符。 URI 简单来理解就是标识/定义了一个资源&#xff0c;而 URL…

python生成json_生成动态嵌套JSON对象和数组-python - python

正如问题所解释的那样&#xff0c;我一直在尝试生成嵌套的JSON对象。在这种情况下&#xff0c;我有for循环从字典dic中获取数据。下面是代码&#xff1a; f open("test_json.txt", w) flag False temp "" start "{\n\t\"filename\"&quo…

彻底弄懂Qt的编码(汉字乱码问题及相关函数作用)

测试1 新建test工程用于测试&#xff0c;main.c文件内容如下&#xff1a; #include <QCoreApplication> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QString str_hanzi("百度"); // 汉字QString str_ascii(&…

【转】1.9 Asp.Net Core 轻松学-多线程之取消令牌(

目录 前言1. 多线程请求合并数据源2. 对长时间阻塞调用的异步取消令牌应用3. CancellationToken 的链式反应4. CancellationToken 令牌取消的三种方式结束语示例代码下载前言 取消令牌(CancellationToken) 是 .Net Core 中的一项重要功能&#xff0c;正确并合理的使用 Cancell…

python怎么改背景_python IDE背景怎么改

首先&#xff0c;在已经下载好的python文件目录下&#xff0c;找到config-highlight.def文件&#xff0c;我的是在H:\python\python3**\Lib\idlelib**文件夹下。 打开文件后&#xff0c;你会看到一些默认的颜色配置&#xff0c;比如经典的颜色配置就是白色背景&#xff0c;一般…

QML程序发布时无法正常运行的解决办法

1、运行依赖 以我的一个项目为例&#xff0c;此程序使用QQuickWidget将QWidget和QML结合。程序debug版发布时依赖的库如下&#xff1a; 大部分dll可以在Visual Studio中调试时的控制台中看出已加载的dll&#xff0c;只需到Qt安装目录下找到对应的dll即可。但是某些dll并没有提…

【转】1.A(译).NET4.X 并行任务中Task.Start()的FAQ

传送门&#xff1a;异步编程系列目录…… 近期有不少人向我咨询关于Task的Start()方法。比如&#xff1a;何时使用及何时不使用Start()、Start()又做了些什么……我想在这里回答一些问题试图澄清和平息任何关于Start()方法是什么以及做了什么的误解。 1. 问题&#xff…

python列表添加数字_Python-识别列表中的连续数字组

小编典典 编辑2&#xff1a;回答OP新要求 ranges [] for key, group in groupby(enumerate(data), lambda (index, item): index - item): group map(itemgetter(1), group) if len(group) > 1: ranges.append(xrange(group[0], group[-1])) else: ranges.append(group[0]…

QML项目笔记

引用资源文件内的资源时&#xff0c;一律加上qrc前缀&#xff0c;如&#xff1a;qrc:/img/avatar.png&#xff0c;否则无法加载。制作聊天气泡的方法&#xff1a;使用BorderImage元素。BorderImage源于CSS3新增的十分强大的border-image属性。可以实现安卓中的 点9图 效果。慎用…

【转】1.B(译).NET4.X并行任务Task需要释放吗?

传送门&#xff1a;异步编程系列目录…… 摘要&#xff1a;本博文解释在.NET 4.X中的Task使用完后为什么不应该调用Dispose()。并且说明.NET4.5对.NET4.0的Task对象进行的部分改进&#xff1a;减轻Task对WaitHandle对象的依赖&#xff0c;并且增强在释放了Task后对其成员的可访…

Qt:QSound无法播放.wav声音的解决办法

从网上下载了音频素材&#xff0c;格式为.wav&#xff0c;用QSound播放&#xff0c;没声音。刚开始放在资源文件里&#xff0c;后来看到有的人说不能引用资源文件里的音频文件&#xff0c;事实证明纯属扯淡&#xff01;改为播放本地文件系统内的音频文件&#xff0c;但是仍然无…

【转】UML基础: 第1部分 - 类图 (Class Diagram)

类图 类图是一个静态图。它代表了应用程序的静态视图。类图不仅用于可视化&#xff0c;描述和记录系统的不同方面&#xff0c;还用于构建软件应用程序的可执行代码。 类图描述了一个类的属性和操作&#xff0c;以及对系统施加的约束。类图被广泛用于面向对象系统的建模&#…

Qt QSS知识点记录

一、border-image的使用 具体使用方法参考css3的相关说明&#xff0c;这里主要记录一个使用技巧。 使用时发现按照css3指定的方法来设置边缘非拉伸区的宽度并没有效果。如 border-image: url(test.png) 10 10 10 10; 后来在网上搜索到一篇文章&#xff0c;提供了一个解决方…

int转换为cstring_PostgreSQL 隐式类型转换探秘

个人简介何小栋&#xff0c; 从事产品研发和架构设计工作&#xff0c;对Oracle、PostgreSQL有深入研究&#xff0c;ITPUB数据库版块资深版主。现就职于广州云图数据技术有限公司&#xff0c;系统架构师&#xff0c;博客&#xff1a;http://blog.itpub.net/6906/摘要本文通过与O…

【转】UML基础: 第 2 部分 - 对象图 (Object Diagram)

对象图是从类图派生的&#xff0c;因此对象图依赖于类图。 对象图表示类图的一个实例。类图和对象图的基本概念是相似的。对象图也表示系统的静态视图&#xff0c;但这个静态视图是系统在特定时刻的快照。 对象图用于呈现一组对象及其关系作为实例。 对象图的目的 图表的目…

Qt 界面设计笔记

1、今天遇到一个情形&#xff0c;在QScrollArea中设置一个QLabel的大小和QScrollArea一样大&#xff0c;设置完立即打印&#xff0c;大小的确是相同的。但是程序启动后&#xff0c;却显示出了滚动条&#xff0c;即QLabel比QScrollArea大。程序运行起来之后在事件响应函数中打印…