如何通过openLooKeng更高效访问HBase?
1. HBase Connector介绍
数据虚拟化引擎openLooKeng中的HBase Connector支持访问Apache HBase集群并进行查询和创建表的操作。用户可以在openLooKeng中创建表,并映射到HBase Cluster中已有的表,支持INSERT、SELECT和DELETE操作。
—— 一个简单的全表扫描的sql的执行,会经历哪些阶段:
首先该sql将要访问的数据,一定是属于某一个数据源的,那么一个通用的Connector需要做哪些事情。Sql的解析是由openLooKeng本身完成的;接下来是生成执行计划,在这个阶段需要验证用户所访问的表的合法性,那么Connector则需要提供该功能(即元数据管理);然后就到了任务调度阶段,openLooKeng会将一个大任务划分为多个小任务,由多个worker分工完成,那么Connector会提供split分割的接口,即SplitManager;Worker在收到任务之后,以分片为最小单元进行数据加载,此时需要用到Connector中的PageSource/PageSink来完成数据的读写操作。所以在HBase Connector中我们实现了这些关键模块(SplitManager,HBaseClient,HetuMetastore)。
HBase Cluster的主要组件:ZooKeeper用来记录一些元数据信息,Master用来处理用户发过来的请求,RegionServer用来执行用户请求并管理Region的分裂和合并。

——HBase Connector数据流:
建表(HBase Connector支持两种模式的建表)。 ① 直接关联远端HBase数据源上的表(即外表的形式) ② 在openLooKeng上创建一张HBase数据源不存在的新表
用户发送一条查询HBase数据的sql请求给Coordinator
Coordinator收到请求后,从hetuMetastore中获取table信息,以验证用户sql所访问表和数据列的合法性
Coordinator通过SplitManager获取所有的分片信息,并生成执行计划和任务,将任务下发到各个Worker上
每个Worker会处理一部分的数据。Worker通过HBase Client来实现对HBase Cluster的数据读写交互
——使用openLooKeng访问HBase集群
配置说明:使用openLooKeng来访问HBase集群,我们需要配置HBase的相关信息在Catalog中,主要是ZooKeeper的信息。创建并编辑etc/catalog/hbase.properties: 具体操作可参考:

HBase Connector所支持的语法: HBase Connector基本上支持所有的SQL语句,包括创建、查询、删除模式,添加、删除、修改表,插入数据,删除行等。以下是一些示例:

算子下推支持:HBase连接器支持下推大部分运算符,如基于RowKey的点查询、基于RowKey的范围查询等。此外,还支持这些谓词条件以进行下推:=、>=、>、<、<=、!=、in、not in、between and。
2.HBase Connector性能分析
openLooKeng1.1.0版本并未对HBase Connector做过全方面的性能优化。 我们先了解一下HBase读取数据的机制。实际上,HBase Client首先会从ZooKeeper中获取HBase表元数据所在的RegionServer,然后根据RowKey,找到数据所在的RegionServer,然后发送读数据请求给RegionServer。

每个RegionServer由多个Region构成,Region是存储数据的最小单元。每个Region里面会维护一定范围的key值。

那么先介绍一下我们之前切片的做法:HBase Client调用API获取数据所在的region信息。每个region的start key和end key组成一个split。Split的个数即数据所分布在的region的个数。
这种情况下,我们没有利用到读取Region的并发能力。我们知道,分片数决定了任务的并发度,影响性能。所以从这个角度出发,需要提高数据读取的并发度。那么在openLooKeng 1.2.0版本中,我们引入了一种新的数据切片方式以及支持访问快照的模式。
3.HBase Connector性能优化
——优化点1(新的分片规则)
建表时指定分片切割规则,提升单表全表扫描性能 create table xxx() with(split_by_char='0~9,a~z,A~Z') split_by_char表示rowKey的第一个字符的范围,为分片切割的依据。 若RowKey的第一个字符由数字构成,则可以根据不同的数字进行分片切割,提高查询并发度。不同类型的符号用逗号隔开。如果设置不当,会导致查询数据结果不完整,请根据RowKey的实际情况进行配置。无特殊要求时,无需修改。默认情况已包含所有的数字和字母。若rowKey为汉字,则create table xxx() with(split_by_char='一~锯');另外,建表时会根据split_by_char指定预分区的splitKey,尽量将数据分散到各个region,那样在进行HBase读写时,对性能会有很好的改善。
HBase Server支持使用startRow和endRow来获取Scanner 比如,splitByChar为0~2,我们会生成一些键值对。键值对的个数将会小于一个常量(如20),所以需要首先计算每个键值对的gap大小。 (startKey = 0, endKey = 0|),(startKey = 1, endKey = 1|),(startKey = 2, endKey = 2|) splitByChar为0~9, a~z (startKey = 0, endKey = 1|),(startKey = 2, endKey = 3|)……(startKey = y, endKey = z|)

——优化点2(支持访问快照模式)

可配置ClientSide模式来读取数据,提升多并发查询性能 ClientSide的工作机制是在HDFS上创建HBase表的Snapshot,记录各个数据文件所在的Region地址,在读取数据时,不需要经过HBase Region Server,而是直接访问Region,这样可以在高并发下降低Region Server的压力。

——性能测试 HBase 3节点,openLooKeng 3节点,e_mp_day_read_52:10138492行,64列


HBase Shell对于操作千万行的表做count操作时,性能会很差;HBase也有提供计算行数的jar包,这里没有进行测试。因为openLooKeng 1.2.0优化了count操作,只会去加载第一列,所以sql1的情况下,Normal Scan和ClientSide方式性能差异不大。Sql2会获取多列数据,当HBase Server成为瓶颈时,ClientSide的优势就凸显出来了。
当然,HBase的应用场景并非是全表扫描,而应该是根据RowKey进行点查询的场景。该场景下,openLooKeng HBase Connector会直接根据RowKey调用对应的API,高效获取数据即可。openLooKeng 1.2.0在具备访问HBase基本功能的前提下,优化了对于全表扫描的场景下的性能,openLooKeng 1.2.0 HBase Connector的全表扫描相比1.1.0版本,性能提升多倍。
如果您还想了解更多,欢迎关注 4月29日晚8:00 B站直播活动,与老师们互动探讨相关的技术问题。

本文作者 | 涂盛霞
授权转载 | 请联系openLooKeng小助手 (微信号:openLooKengoss)