写流程
- 1.Client从缓存中定位region,没有则访问zookeeper,获取meta表所在的Region Server位置
- 2.去相应的Region Server获取meta表,存到Client的缓存里
- 3.从meta表中获取region信息,得到Namespace、表名和RowKey等相关信息,并获取将要写入Region的位置
- 4.Client向上一步HRegionServer发出写请求,HRegionServer先将操作和数据写入HLog(预写日志,Write Ahead Log,WAL),再将数据写入MemStore,并保持有序。
注意:关于java中写日志底层源码的实现
- 获取锁
- 更新最后的时间戳
- 构建WAL
- 追加日志,但是不同步
- 写到内存
- 释放锁
- 同步WAL,如果内存出现异常就回滚了,保证内存和WAL同时成功
- 5.当MemStore的数量超过阈值时,将数据溢写到磁盘生成一个StoreFile文件。当Store中StoreFile的数量超过阈值时,将若干小StoreFile合并(Compact)为一个大StoreFile。 当Region中最大Store的大小超过阈值时,Region分裂(Split),等分成两个子Region。
读过程
- 1.获取region的位置信息,跟写获取一样
- 2.Client向HRegionServer发出读请求。
- 3.读MemStore和StoreFile的数据,比较时间戳后,返回给用户。
flush时机
- Memstore级别限制:当Region中任意一个MemStore的大小达到了上限(hbase.hregion.memstore.flush.size,默认128MB),会触发Memstore刷新。
- Region级别限制:当Region中所有Memstore的大小总和达到了上限(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默认 2* 128M = 256M),会触发memstore刷新。
- Region Server级别限制:当一个Region Server中所有Memstore的大小总和达到了上限(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认 40%的JVM内存使用量),会触发部分Memstore刷新。Flush顺序是按照Memstore由大到小执行,先Flush Memstore最大的Region,再执行次大的,直至总体Memstore内存使用量低于阈值-
- HBase定期刷新Memstore(默认1小时)