hbase(一) : HTable

如题所述

第1个回答  2022-07-20

hbase1.3
HTable 是我们对数据读取,操作的入口, implements HTableInterface, RegionLocator

内部构造

有一个检查 的动作待详细查看.

关于BufferedMutator, 是用来缓存客户端的操作的, hbase 将客户端的DML抽象成了 Mutation , 子类有: Append, Delete, Increment, Put 操作.
put方法将Put对象包装成Mutation,交给BufferedMutator, 到达设置的大小限制,或者主动调用flush操作, 会触发 backgroundFlushCommits(boolean synchronous) 操作, 然后Mutation由 AsyncProcess 提交,详细查看 BufferedMutatorImpl 类.
由 AscncProcess 提交后, (注释:Action类是将行与对应操作结合的类), 由connection去寻找每一行对应的region位置, 包装action, server, region等信息添加到 MutiAction 中去, 这个类持有按照region分组的actions,

然后会对每个action都创建 SingleServerRequestRunnable (rpc caller 和rpc callable, caller call callable), 交给线程池去运行.

删除操作很简单: 创建 RegionServerCallable , 然后rpc工厂类创建rpc caller来调用它

get和scan都是继承了Query
get很简单:首先检查,这个get是否只是检查数据存在否, 并且检查是否指定了一致性等级(默认 (Consistency.STRONG) ), 之后创建rpc请求Request, 如果 不是强一致性Consistency.TIMELINE , 则调用 RpcRetryingCallerWithReadReplicas , 它可以从replica上读取, 返回的数据被标记为stale(读操作是通过 Consistency.TIMELINE ,然后读RPC将会首先发送到主region服务器上,在短时间内(hbase.client.primaryCallTimeout.get默认为10ms),如果主region没有响应RPC会被发送到从region。 之后结果会从第一个完成RPC的返回。如果响应是来自主region副本,我们就会知道数据是最新的,Result.isStale() API是检查过期数据,如果结果是 从region返回,那么Result.isStale()为true,然后用户就可以检查关于过期数据可能的原因。).

当replica_id=0的regin不可以时候, 给所有的replica region发送请求,获取第一个从这些replica返回的数据, 客户端可以 Result.isStale()检查是否是来自副本的数据

Scan 类可以设置一系列的属性, startkey,endkey, 过滤器, 版本,缓存,最大取回大小等等, 但是获取数据是由 getScanner(Scan)返回的 ResultScanner 操作的.
返回的 ResultScanner 有small, Reversed,big和纯client 的不同,

什么是small scan?

见 https://issues.apache.org/jira/browse/HBASE-7266

hbase里面有两种读操作:pread and seek+read.
pread是一个函数,用于带偏移量地原子的从文件中读取数据。
读路径: https://yq.aliyun.com/articles/602377/
seek + read is fast but can cause two problem:
(1) resource contention
(2) cause too much network io

另外,一些其他的解释:前者适合小于一个数据块(默认64k)的smallScan(openScanner, next, closeScanner将在同一次rpc中实现);而后者则会使用hdfs预读取,在DN中缓存一些数据(HBASE-7266、HBASE-9488)

查看最普通的 ClientScanner , 初始化的时候调用 initializeScannerInConstruction , 这个方法去调用 nextScanner() , 获取为下一个region准备的scanner , 这个scanner会发起rpc调用, 参数是 ScannerCallable 对象, 这是scanner 的动作的抽象, reversed 和 small 都有对应的 ScannerCallable 子类
ScannerCallable 在初始化后, 的prepare阶段, 会从对应的region,获取对应的server, 获取这个server的ClientService.BlockingInterface接口, 并设置, 以便被调用的时候知道该向谁发起rpc请求

call阶段, 在创建 RequestScan的时候, 参数nextCallSeq在client和server端都维持,,每次调用都会增加, 是为了client能正确获取下一批的数据 .

相似回答