hbase ycsb 测试 hbasescan_hbase ycsb 测试


今天来讲讲HBase读的过程:

1、HBase读过程详解

2.1影响HBase读取命令的参数

HBase读包含两种命令:get ,基于确切的RowKey去获取一行数据,通常被称之为随机点查;scan,指定一个RowKey的范围区间,获取该区间的所有记录,当区间未明确指定时,scan退化为全表扫描;


hbase ycsb 测试 hbasescan_表结构_02


图2.1 client端scan的示意图

Client每一次往RegionServer发送scan请求,都会批量拿回一批数据(由Caching决定每一次拿回的Results数量),然后放到本次的Result Cache中:应用每一次读取数据都是从本地的Result Cache中获取的,如果Result Cache中的数据读完了,则Client会再次往RegionServer发送scan请求获取更多的数据。此处有8个编程参数会影响读取过程:

①Caching: 设置一次RPC请求批量读取Results的数量;scan.setCaching(100);

②Batch: 设置每一个Result中的列的数量;scan.setBatch(10);

③Limit: 限制一次Scan操作所获取的行的数量;scan.setLimit(1000);

④Cache Block: RegionServer侧是否要缓存本次Scan所涉及的HFileBlocks;scan.setCacheBlocks(true);

⑤Raw Scan: 是否可以读取到删除标识以及被删除但尚未被清理的数据;scan.setRaw(true);

⑥MaxResultSize: 从内存占用量的维度限制一次Scan的返回结果集;scan.setMaxResultSize(5*1024*1024);

⑦Reversed Scan: 反向扫描,普通的Scan操作是按照字典顺序从小到大的顺序读取的,而Reversed Scan则恰好相反:scan.setReversed(true);

⑧带Filter的Scan,Filter可以在Scan的结果集基础之上,对返回的记录设置更多条件值,这些条件可以与RowKey有关,可以与列名有关,也可以与列值有关,还可以将多个Filter条件组合在一起等;scan.setFilter(filter);

2.2读取过程详述

Client发送读取请求后,整个读取过程叙述如下:

2.2.1 定位Region

定位请求关联的Region的时候,对于get定位与rowkey参数关联的region;对于scan先定位与starRow参数关联的region;过程详述如下:

2.2.1.1找到-ROOT-表

要根据查询参数的rowkey找到到对应的结果数据,需要先找-ROOT-表,-ROOT-表中存放了.META.表是由哪个regionServer管理的信息,而.META.表保存了Hbase中所有数据表的region的位置信息。要找-ROOT-表,则需要先与zookeeper通信,找到管理-ROOT-表的RegionServer的地址,这个地址存在zookeeper中,默认值是:/hbase/root-region-server;找到管理-ROOT-表的Regionserver的地址后,就可以与这个RegionServer通信,获取到-ROOT-表的内容,-ROOT-表的内容如下:


hbase ycsb 测试 hbasescan_数据_03

表2.2.1.1.1 -ROOT-表结构

可以看到,-ROOT-表的内容包含了各个RegionServer上都管理了哪些.META.表的信息,这些.META.表中又有哪些Region,相关的rowkey在怎样的范围等信息,因此通过rowkey可以在-ROOT-表中找到具体和rowkey相关的.META.表所在的regionServer地址信息;因.META.表也是有region的,也会不断进行分裂的,所以需要记录timestamp,查找的时候要找最新timestamp对应的记录;

每个regionServer启动的时候,都会分配一个startcode,和host,port,startcode统一构成一个regionserver的唯一标志,所以一台机器重启前后其实是两个不同rs。

注意:-ROOT-表只有一个region,且永远不会分裂;


hbase ycsb 测试 hbasescan_hbase scan超时设置_04

图2.2.1.1.1 -ROOT-表示例

2.2.1.2找到.META.表

通过-ROOT-表找到某个regionServer上的.META.表后,可以通过.META.表来找到rowkey相关的Region,我们来看看.META.表的结构:


hbase ycsb 测试 hbasescan_hbase scan超时设置_05

表2.2.1.2.1.META.表结构

可以看到,.META.表结构和-ROOT-表结构完全一致,只是rowkey构成不同;因此通过rowkey可以找到管理region的RegionServer的地址;


hbase ycsb 测试 hbasescan_hbase ycsb 测试_06

图2.2.1.2.1.META.表示例

注意:由于一个HBase数据库中会存在很多表,也会存在很多region,因此.META表会非常大,而.META.表只是HBase中的一张普通表,因此本身也需要分裂成多个region,所以.META.表会存在与多个Regionserver上,这也是为什么需要设置-ROOT-表的原因。.META.表一般都全部加载在内存中;

当然 HBase 客户端会缓存这些寻址的数据,只有在数据失效或无相关数据的时候才会按照上面的流程定位到对应的 RegionServer。

从.META.表中得到管理region的Regionserver后,连接对应的RegionServer,发送读取Region的请求;

2.2.1.3找到对应的Region后的过程

向regionserver发送读取请求,之后的过程如下图:


hbase ycsb 测试 hbasescan_sed_07

2.2.1.3.1 找到Region后RegionServer读取扫描数据的过程

这里有三种情况:

①对于新写入的Cell数据,它可能会存在于MemStore中;

②对于已经Flush到HFile中的Cell数据,它会存在于某个或某些StoreFile(HFile)中;

③对于刚读取过的Cell数据,它可能存在于BlockCache中;

所以对于任意数据,Cel上数据可能存储在三个地方,在读取的时候需要扫瞄这三个地方,然后将结果合并即可(Merge Read),RegionServer中扫描的顺序依次是:BlockCache、MemStore、StoreFile(HFile)。

其中StoreFile的扫描先会使用Bloom Filter过滤那些不可能符合条件的HFile,然后读取HFile中的Trailer,将Data Block Index读入内存,这样,检索某个rowkey时,不需要扫描整个HFile,而只需从内存中找到rowkey所在的data block,通过一次磁盘io将整个 data block读取到内存中,再找到需要的rowkey。使用Block Index快速定位到数据后,将其加载到BlockCache中,然后从BlockCache中读取数据。

这里要注意,一个HStore可能存在多个StoreFile(HFile),此时需要扫瞄多个HFile,如果HFile过多,则会引起性能问题,因此需要对HFile进行Compation。

如果觉得有用,记得关注点赞哦,:)