HBase之HRegionServer处理put请求

来源:互联网 发布:mac模糊搜索文件 编辑:程序博客网 时间:2024/05/22 06:25

我们知道客户端是通过MultiServerCallable.call()调用multi()来进行RPC请求的。

1 RegionServer在接受到客户端写请求后,首先反序列化PUT对象,然后判断操作是否是原子性的,如果不是原子性的则调用doNonAtomicRegionMutatiOn操作

 

2 获取PUT请求中的row key,family,以及qualifier等信息

 

3 检查RegionServer上MemStore是否超过当前堆内存使用率的百分比,默认是0.4,你也可以通过hbase.regionserver.global.memstore.upper

Limit去配置;如果超过限制则唤醒Flush线程把当前占用内存最大的memstores,直到低于最低限制,参考参数hbase.regionserver.global.

memstore.lowerLimit

 

4 然后检查Region是否只读,检查当前Region的MemStore是否大于blockingMemStoreSize=(hbase.hregion.memstore.flush.size* hbase.

hregion.memstore.block.multiplier) ,如果大于则进行flush操作,释放内存

 

注意:

hbase.hregion.memstore.flush.size: 默认大小128M

hbase.hregion.memstore.block.multiplier: 默认倍数2倍

我们考虑一种情况,理想情况memstore达到128M时,就该刷新到StoreFile但是,这时候MemStore的数据是127M,然后下一个请求写的数据是100M,这时候MemStore会涨到会涨到228M > 128M,那么发生OOM的风险就增大了,所以HBase就让MemStore现在实际大小 超过默认hbase.hregion.memstore.block.multiplier倍时就暂时block该Region 的请求,然后进行flush,释放内存。

这两个参数的设置需要进行综合权衡,因为一旦flush了之后,就有可能发生compact、split操作,这时候是比较耗时的,可能达到十几秒之类的,如果是online应用是不可接受,我们可以适当增加hbase.hregion.memstore.block.multiplier这个倍数,然后内存不够用的话,还可以加内存。

 

 

以上步骤完成则正式进入写核心的写流程:


5 构造WALEdit

 

6 获取行锁,锁定row,如果之前还有事务未结束,等待之前的事务结束,获取Region更新锁,防止多个请求同时更新Region

 

7 从MultiVersionConsistencyControl(MVCC)获取一个Write Number,

主要用于HBase的在并发情况下的写一致性的前提下,保证高性能读取;构造一个往MemStore写的入口类WriteEntry

 

8 从PUT请求中获取<family,cell>映射,然后检查family,更新这次请求的时间戳,并设置到这次请求中,然后把这个操作放到一个集合中

 

9 遍历PUT操作的集合,获取每一个单元格,然后将其添加到WALEdit

 

10 遍历PUT操作集合,遍历每一个单元格,然后将其写入MemStore

 

11 遍历WALEdit,将日志添加到HLog中

 

12 释放Region更新锁和行锁

 

13 同步这WALEdit

 

14 最后会检查MemStore是否应该flush,如果满足flush条件,则进行flush操作