HBase 内存调优¶
内存调优主要目的是:合理规划memstore的内存分配,提高写入性能。
注意以下几点:
- 应当开启CMS的内存压缩功能,防止memstore算盘后堆区出现内存碎片。过多内存碎片可能导致新生代升级失败,触发GC;
- memstore的刷盘阈值,要和region数目匹配。原则上:(RegionServer内存 * 分配给MemStore比例) > (Memstore 大小 * 列簇数量),当然有一到二倍的超配问题也不大。
- 使用bulk load时,需要注意hbase.hregion.memstore.block.multiplier配置。该配置指:单个Memstore的大小超过指定倍数(2倍)时 ,region会阻止新的写入并且触发flush。 一旦region被锁住,regionserver隔一段时间再检查memstore是不是低于阀值。这会导致hbase.server.thread.wakefrequency(10s)之内无法再写入。
- 避免 hbase.hstore.blockingStoreFiles 到达上限,导致region。block
MemStore 触发 flush 的场景¶
- 单个memstore的内存达到,hbase.hregion.memstore.flush.size 触发写盘。但是此时不会锁住region。
- 单个memstore的内存达到,hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier。触发flush,并且锁住该region。hbase.hregion.memstore.flush.size这个配需要考虑RS中Region数目,在压力测试中,由于Client一直在写入,该参数太大非常容易照成memstore内存到达高水位线,导致整个RS block,
- memstore的总内存达到 hbase.regionserver.global.memstore.lowerLimit (0.35),此时最大memstore发生flush。
- memstore的总内存达到 hbase.regionserver.global.memstore.upperLimit (0.4), 此时所有RS发生flush,此时整个RS阻塞。
- WAL大小达到上限,hbase.regionserver.hlog.blocksize * hbase.regionserver.maxlogs(2GB),这个值应该大于lowerLimit的值,flush不应该由这个条件触发
建议:
hbase.hregion.memstore.flush.size * Region num = hbase.regionserver.global.memstore.upperLimit * RS JVM Mem 根据上面的公式,除了Region Num数目以外,其他参数在生产中都是固定的。平时定位HBase性能问题时,我们可以通过判断当前RS中的Region数目来判断,HBase需不需要扩容。
HBase的查询性能¶
通过 hfile.block.cache.size(0.2) 配置直接影响数据读的性能。通常情况下,upperLimit和该配置的和,应该小于0.8,否则容易OOM。
频繁触发MemStore 同样会影响读性能¶
-
频繁flush,产生大量的HFile。这样HBase在检索的时候,就不得不读取大量的HFile,读性能会受很大影响。
-
过多的合并会产生额外的负载。
-
当Compaction处理是跟集群上的其他请求并行进行的,当HBase不能及时完成Compaction的时候(同样有阈值设置项),会在RS上出现“写阻塞”。
MSLAB¶
MSLAB可以避免HBase发生长时间的Full GC,但是这样可能导致内存利用率下降,已经性能的下降,通过G1+MSLAB,几乎可以完全杜绝Full GC。
hbase.hregion.memstore.mslab.enabled:设置为true,即打开MSLAB,默认是true。
hbase.hregion.memstore.chunkpool.maxsize:表示在整个Memstore可以占用的堆内存的比例。默认值是0,因此设置大于0,才算真正开启MSLAB.
hregion.memstore.chunkpool.initialsize:表示在RegionServer启动的时候预分配一些chunk出来。也是一个比例值,该值表示预分配的chunk占用总的chunkpool的大小。
hbase.hregion.memstore.mslab.chunksize:每一个chunk的大小,默认是2048*1024,即2MB。
hbase.hregion.memstore.mslab.max.allocation:能放入chunk的最大单元格大小,默认是256KB,已经很大了。
参考:https://juejin.im/post/5c024eedf265da611e4d64f4
压缩算法¶
当CPU性能足够时,开启压缩能够提升读写能力。原因是:CPU计算使用的时间,通常小于IO时间。
HStore¶
HStore对应了table中的一个CF列族,包含:MemStore和StoreFile(底层实现是HFile)。当其中一个CF的Memstore达到阈值flush时,会创建一个新的StoreFile。
StoreFile以HFile格式保存在HDFS上,HFile是Hadoop的二进制格式文件。实际上StoreFile就是对HFile做了轻量级包装,即StoreFile底层就是HFile。
PS: 某个column family在flush的时候,它邻近的column family也会因关联效应被触发flush,最终导致系统产生更多的I/O???是这样的吗?
| 参数名 | 默认值 | 说明 |
|---|---|---|
| hbase.hregion.majorcompaction | 默认为7天 | 配置major合并的间隔时间,默认为1天,可设置为0,禁止自动的major合并,可手动或者通过脚本定期进行major合并。major合并之后,一个store只有一个storeFile文件,会对store的所有数据进行重写,有较大的性能消耗。 |
| hbase.hstore.compactionThreshold/hbase.hstore.compaction.min | 3 | hstore大于三个的时候,开始minor 合并 |