一、客户端寻找HRegionServer,及缓存位置信息

hbase regionservers hbase regionserver数据存在哪里_数据

从这个过程中,我们发现客户会缓存这些位置信息,然而第二步它只是缓存当前RowKey对应的HRegion的位置,因而如果下一个要查的RowKey不在同一个HRegion中,则需要继续查询hbase:meta所在的HRegion,然而随着时间的推移,客户端缓存的位置信息越来越多,以至于不需要再次查找hbase:meta Table的信息,除非某个HRegion因为宕机或Split被移动,此时需要重新查询并且更新缓存。

二、写数据流程

  • 首先通过上文讲的找到该写数据最终需要去的HRegionServer;
  • 然后客户端将写请求发送给相应的HRegionServer,在HRegionServer中它首先会将该写操作写入WAL(Hlog)日志文件中(Flush到磁盘中)。
  • 写完WAL日志文件后,HRegionServer根据Put请求中的TableName和RowKey,startkey、endkey找到对应的HRegion,并根据Column Family找到对应的HStore,并将数据写入到该HStore的MemStore中。此时写成功,并返回通知客户端(到memstore客户端就知道成功了)。

HBase写数据时序图:

hbase regionservers hbase regionserver数据存在哪里_客户端_02

写入MemStore后的操作:

  1. 存入MemStore,一直到MemStore满
  2. Flush成一个StoreFile,直至增长到一定阈值
  3. 出发Compact合并操作 -> 多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除(老版本)
  4. 当StoreFiles Compact后,逐步形成越来越大的StoreFile
  5. 单个StoreFile大小超过一定阈值(Region split 阈值)后,触发Split操作,把当前Region Split成2个Region,Region会下线,新Split出的2个子Region会被HMaster分配到相应的HRegionServer上,使得原先1个Region的压力得以分流到2个Region上;

hbase regionservers hbase regionserver数据存在哪里_客户端_03

什么时候执行MemStore Flush?

  • 当一个MemStore的大小超过了hbase.hregion.memstore.flush.size的大小,此时当前的HRegion中所有的MemStore会Flush到HDFS中。不阻塞写操作(Region级别的flush)
  • 当全局MemStore的大小超过了hbase.regionserver.global.memstore.upperLimit(默认0.4,memstores所占最大堆空间比例)的大小,此时当前HRegionServer中所有HRegion中的MemStore都会Flush到HDFS中。阻塞写操作(HRegionServer级别的flush)
  • 当一个Region的MemStore总量达到hbase.hregion.memstore.block.multiplier.*habse.hregion.memstore.flush.size(默认2*128M=256M)时,会阻塞这个region的写操作,并强制刷新到HDFS中,触发这个刷新只会发生在Memstore即将写满128M时put了一个巨大的记录的情况,这时会阻塞写操作,强制刷新成功才能继续写入。(Region级别的flush)
  • 当前HRegionServer中HLog的大小超过阈值,当前HRegionServer中所有HRegion中的MemStore都会Flush到HDFS中。阻塞写操作(HRegionServer级别的flush)

三、读数据流程

  1. 首先找到要读的数据的HRegionServer。
  2. 根据读取的TableName和RowKey的startkey 、 endkey 找到对应的HRegion。
  3. 每个regionserver只有一个blockcache(读缓存),读取数据时,先到memestore上读数据,找不到再到blockcahce上找数据,再查不到则到磁盘(storefile)查找,并把读入的数据同时放入blockcache。

hbase regionservers hbase regionserver数据存在哪里_缓存_04