Hbase的数据刷写

Hbase数据刷写

触发时机

  • Region 中所有 MemStore 占用的内存超过相关阈值

    • hbase.hregion.memstore.flush.size 参数控制,默认为128MB
    • 如果我们的数据增加得很快,
      达到了 hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier
      的大小,hbase.hregion.memstore.block.multiplier 默认值为4,
      也就是128*4=512MB的时候,
      那么除了触发 MemStore 刷写之外,HBase 还会在刷写的时候同时阻塞所有写入该 Store 的
      写请求!
  • 整个 RegionServer 的 MemStore 占用内存总和大于相关阈值

    • HBase 为 RegionServer 所有的 MemStore 分配了一定的写缓存(),大小等于
      • hbase_heapsize(RegionServer 占用的堆内存大小)*
        hbase.regionserver.global.memstore.size(默认值是 0.4)。
    • 如果整个 RegionServer 的 MemStore 占用内存总和大于阈值将会触发 MemStore 的刷写。
      • hbase.regionserver.global.memstore.size.lower.limit (默认值为 0.95)* MAX_SIZE
    • 例如:HBase 堆内存总共是 32G ,MemStore 占用内存为:32 * 0.4 * 0.95 = 12.16G将触发
      刷写
    • 如果达到了 RegionServer 级别的 Flush,当前 RegionServer 的所有写操作将会被阻塞,这
      个阻塞可能会持续到分钟级别。
  • WAL数量大于相关阈值

    • 数据到达 Region 的时候是先写入 WAL,然后再被写到 Memstore 。

    • 如果 WAL 的数量越来越大,这就意味着 MemStore 中未持久化到磁盘的数据越来越多。

    • 当 RS 挂掉的时候,恢复时间将会变得很长,所以有必要在 WAL 到达一定的数量时进行一次
      刷写操作

    • max(32, hbase_heapsize * hbase.regionserver.global.memstore.size * 2 /
      logRollSize)

  • 定期自动刷写

    • hbase.regionserver.optionalcacheflushinterval
    • 默认值 3600000(即 1 小时),HBase 定期 Flush 所有 MemStore 的时间间隔。
    • 一般建议调大,比如 10 小时,因为很多场景下 1 小时 Flush 一次会产生很多小文件,一方
      面导致 Flush 比较频繁,另一方面导致小文件很多,影响随机读性能
  • 数据更新超过一定阈值

    • 如果 HBase 的某个 Region 更新的很频繁,而且既没有达到自动刷写阀值,也没有达到内存
      的使用限制,但是内存中的更新数量已经足够多
    • 比如超过 hbase.regionserver.flush.per.changes 参数配置,默认为30000000,那么也是会
      触发刷写的。
  • 手动触发刷写

    • Shell 中通过执行 flush 命令

    • hbase> flush ‘TABLENAME’
      hbase> flush ‘REGIONNAME’
      hbase> flush ‘ENCODED_REGIONNAME’
      hbase> flush ‘REGION_SERVER_NAME’

  • 特别注意

    • 以上所有条件触发的刷写操作最后都会检查对应的 HStore 包含的 StoreFiles 文件数是否超过
      hbase.hstore.blockingStoreFiles 参数配置的个数,默认值是16。
    • 如果满足这个条件,那么当前刷写会被推迟到hbase.hstore.blockingWaitTime 参数设置的时
      间后再刷写。
    • 在阻塞刷写的同时,HBase 还会请求 Compaction 或者Split 操作。

刷写策略

  • HBASE1.1之前
    • MemStore 刷写是 Region 级别的。就是说,如果要刷写某个 MemStore ,MemStore 所在
      的 Region 中其他 MemStore 也是会被一起刷写的
  • HBASE2.x之后
    • FlushAllStoresPolicy
      • 每次刷写都是对 Region 里面所有的 MemStore 进行的
    • FlushAllLargeStoresPolicy
      • 判断 Region 中每个 MemStore 的使用内存是否大于某个阀值,大于这个阀值的
        MemStore 将会被刷写。
      • flushSizeLowerBound = max((long)128 / 3, 16) = 42
    • FlushNonSloppyStoresFirstPolicy

刷写流程

  • prepareFlush 阶段
    • 刷写的第一步是对 MemStore 做 snapshot
    • 为了防止刷写过程中更新的数据同时在 snapshot 和 MemStore 中而造成后续处理的困难
    • 所以在刷写期间需要持有 updateLock 。持有了 updateLock 之后,这将阻塞客户端的写操
      作。
    • 所以只在创建 snapshot 期间持有 updateLock
    • 而且 snapshot 的创建非常快,所以此锁期间对客户的影响一般非常小。
    • 对 MemStore 做 snapshot 是 internalPrepareFlushCache 里面进行的。
  • flushCache 阶段
    • 如果创建快照没问题
    • 那么返回的 result.result 将为 null。
    • 这时候我们就可以进行下一步 internalFlushCacheAndCommit。
    • 其实 internalFlushCacheAndCommit 里面包含两个步骤:flushCache 和 commit 阶段。
      • flushCache 阶段:
        其实就是将 prepareFlush 阶段创建好的快照写到临时文件里面,
        临时文件是存放在对应 Region 文件夹下面的 .tmp 目录里面
      • commit 阶段:
        将 flushCache 阶段生产的临时文件移到(rename)对应的列族目录下面,
        并做一些清理工作,比如删除第一步生成的 snapshot。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值