hbase.hregion.max.filesize应该设置多少合适

14次阅读
没有评论

本篇内容主要讲解“hbase.hregion.max.filesize 应该设置多少合适”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“hbase.hregion.max.filesize 应该设置多少合适”吧!

1 hbase.hregion.max.filesize 应该设置多少合适
默认值:256M
说明:Maximum HStoreFile size. If any one of a column families HStoreFiles has grown to exceed this value, the hosting HRegion is split in two.

HStoreFile 的最大值。如果任何一个 Column Family(或者说 HStore)的 HStoreFiles 的大小超过这个值,那么,其所属的 HRegion 就会 Split 成两个。

调优:

hbase 中 hfile 的默认最大值 (hbase.hregion.max.filesize) 是 256MB,而 google 的 bigtable 论文中对 tablet 的最大值也推荐为 100-200MB,这个大小有什么秘密呢?
众所周知 hbase 中数据一开始会写入 memstore,当 memstore 满 64MB 以后,会 flush 到 disk 上而成为 storefile。当 storefile 数量超过 3 时,会启动 compaction 过程将它们合并为一个 storefile。这个过程中会删除一些 timestamp 过期的数据,比如 update 的数据。而当合并后的 storefile 大小大于 hfile 默认最大值时,会触发 split 动作,将它切分成两个 region。
lz 进行了持续 insert 压力测试,并设置了不同的 hbase.hregion.max.filesize,根据结果得到如下结论:值越小,平均吞吐量越大,但吞吐量越不稳定;值越大,平均吞吐量越小,吞吐量不稳定的时间相对更小。

为什么会这样呢?推论如下:

   a 当 hbase.hregion.max.filesize 比较小时,触发 split 的机率更大,而 split 的时候会将 region offline,因此在 split 结束的时间前,访问该 region 的请求将被 block 住,客户端自我 block 的时间默认为 1s。当大量的 region 同时发生 split 时,系统的整体访问服务将大受影响。因此容易出现吞吐量及响应时间的不稳定现象
   b 当 hbase.hregion.max.filesize 比较大时,单个 region 中触发 split 的机率较小,大量 region 同时触发 split 的机率也较小,因此吞吐量较之小 hfile 尺寸更加稳定些。但是由于长期得不到 split,因此同一个 region 内发生多次 compaction 的机会增加了。compaction 的原理是将原有数据读一遍并重写一遍到 hdfs 上,然后再删除原有数据。无疑这种行为会降低以 io 为瓶颈的系统的速度,因此平均吞吐量会受到一些影响而下降。
    综合以上两种情况,hbase.hregion.max.filesize 不宜过大或过小,256MB 或许是一个更理想的经验参数。对于离线型的应用,调整为 128MB 会更加合适一些,而在线应用除非对 split 机制进行改造,否则不应该低于 256MB

2 autoflush=false 的影响

无论是官方还是很多 blog 都提倡为了提高 hbase 的写入速度而在应用代码中设置 autoflush=false,然后 lz 认为在在线应用中应该谨慎进行该设置。原因如下:

a autoflush=false 的原理是当客户端提交 delete 或 put 请求时,将该请求在客户端缓存,直到数据超过 2M(hbase.client.write.buffer 决定)或用户执行了 hbase.flushcommits()时才向 regionserver 提交请求。因此即使 htable.put()执行返回成功,也并非说明请求真的成功了。假如还没有达到该缓存而 client 崩溃,该部分数据将由于未发送到 regionserver 而丢失。这对于零容忍的在线服务是不可接受的。

b autoflush=true 虽然会让写入速度下降 2 - 3 倍,但是对于很多在线应用来说这都是必须打开的,也正是 hbase 为什么让它默认值为 true 的原因。当该值为 true 时,每次请求都会发往 regionserver, 而 regionserver 接收到请求后第一件事就是写 hlog,因此对 io 的要求是非常高的,为了提高 hbase 的写入速度,应该尽可能高地提高 io 吞吐量,比如增加磁盘、使用 raid 卡、减少 replication 因子数等

3 从性能的角度谈 table 中 family 和 qualifier 的设置
对于传统关系型数据库中的一张 table,在业务转换到 hbase 上建模时,从性能的角度应该如何设置 family 和 qualifier 呢?
最极端的,①每一列都设置成一个 family,②一个表仅有一个 family,所有列都是其中的一个 qualifier,那么有什么区别呢?

从读的方面考虑:
family 越多,那么获取每一个 cell 数据的优势越明显,因为 io 和网络都减少了。

如果只有一个 family,那么每一次读都会读取当前 rowkey 的所有数据,网络和 io 上会有一些损失。

当然如果要获取的是固定的几列数据,那么把这几列写到一个 family 中比分别设置 family 要更好,因为只需一次请求就能拿回所有数据。

从写的角度考虑:

首先,内存方面来说,对于一个 Region,会为每一个表的每一个 Family 分配一个 Store,而每一个 Store,都会分配一个 MemStore,所以更多的 family 会消耗更多的内存。
其次,从 flush 和 compaction 方面说,目前版本的 hbase,在 flush 和 compaction 都是以 region 为单位的,也就是说当一个 family 达到 flush 条件时,该 region 的所有 family 所属的 memstore 都会 flush 一次,即使 memstore 中只有很少的数据也会触发 flush 而生成小文件。这样就增加了 compaction 发生的机率,而 compaction 也是以 region 为单位的,这样就很容易发生 compaction 风暴从而降低系统的整体吞吐量。
第三,从 split 方面考虑,由于 hfile 是以 family 为单位的,因此对于多个 family 来说,数据被分散到了更多的 hfile 中,减小了 split 发生的机率。这是把双刃剑。更少的 split 会导致该 region 的体积比较大,由于 balance 是以 region 的数目而不是大小为单位来进行的,因此可能会导致 balance 失效。而从好的方面来说,更少的 split 会让系统提供更加稳定的在线服务。而坏处我们可以通过在请求的低谷时间进行人工的 split 和 balance 来避免掉。
    因此对于写比较多的系统,如果是离线应该,我们尽量只用一个 family 好了,但如果是在线应用,那还是应该根据应用的情况合理地分配 family。

4 hbase.regionserver.handler.count

 RegionServer 端开启的 RPC 监听器实例个数,也即 RegionServer 能够处理的 IO 请求线程数。默认是 10.

  此参数与内存息息相关。该值设置的时候,以监控内存为主要参考。

  对于   单次请求内存消耗较高的 Big PUT 场景(大容量单次 PUT 或设置了较大 cache 的 scan,均属于 Big PUT)或 ReigonServer 的内存比较紧张的场景,可以设置的相对较小。

  对于   单次请求内存消耗低,TPS(TransactionPerSecond,每秒事务处理量)要求非常高的场景,可以设置的相对大些。

到此,相信大家对“hbase.hregion.max.filesize 应该设置多少合适”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!