hbase调优参数整理

hbase调优参数整理
BlockCache:
一个 RegionServer只有一个BlockCache。
BlockCache的诞生就是用来优化读取性能的。
现在BlockCache 目前主要有LRUBlockCache,BucketCache等。

LRUBlockCache是目前默认的blockcache方案,基于jvm heap 的lru方案 读取到的数据都被缓存到该内存中,当缓存满时使用lru 算法淘汰数据。
LRUBlockCache有三段缓存 单次读取区(25%)多次读取区(50%)in-memory(25%,存放那些被设置了IN-MEMORY=true的列族中读取出来的block,HBase 元数据比如 meta 表、namespace 表也都缓存在 in-memory 区)类似于jvm中的新生代 老年代 永久代

单次读取区中的数据被多次读取后会晋升到多次读取区 然而因为其使用的是cms,采用 标记清除算法进行GC 随着时间推移 内存中的数据越来越多,内存碎片也越来越多 必然会发生full GC影响系统的性能

BucketCache 解决LruBlockCache的GC缺点,不会出现大量碎片导致Full GC的情况发生
有多种cache方式(heap,offheap(默认),file)。
hbase调优参数整理

初始化的时候申请14个不同大小的Bucket,每个Bucket的大小上限为最大尺寸的Block * 4。
hbase.bucketcache.bucket.sizes可以由该参数配置定义bucket的大小种类
当读取过来的数据会选则一个最相近大小的bucket存放,如果一个种类的buckt内存不够用时可以借用其他bucket的内存,所以不存在内存效率低的问题。
且删除时会整个删除掉bucket中的一个块,所以也不会产生内存碎片问题

combinedcache模式
hbase.bucketcache.combinedcache.enabled (默认为ture)
由LRUBlockCache存放元数据等信息,由bucketcache存放datablock

RegionServer进程的内存就是JVM内存,主要分为三部分:LRUBlockCache,用于读缓存;MemStore,用于写缓存;Other,用于RS运行所必须的其他对象
在bucketcache为offheap的模式下 堆外还有一块内存 存放datablock

一,hfile.block.cache.size
设置blockcache的大小,默认为0.4.读请求先到memstore中查数据,查不到就到blockCache中查,再查不到就到磁盘上读,并把读的结果放入blockCache。
在线上模式中一般使用BucketCache,BucketCache分为了两层,L1采用LRUBlockCache,主要存储HFile中的元数据Block,L2采用BucketCache,主要存储业务数据Block。因为只用来存储元数据Block,所以只需要设置很小的Cache即可。Blockcache和bucketcache的大小比大约在1比9.

二,hbase.bucketache.size
BucketCache的大小,用于缓存实际用户数据Block。初始化的时候申请14个不同大小的Bucket,每个Bucket的大小上限为最大尺寸的Block * 4。根据自己的物理内存大小和实际情况设置该值
三,hbase.bucketcache.ioengine
BucketCache可以有三种工作模式:heap、offheap、file。heap模式表示这些Bucket是从JVM Heap中申请,offheap模式使用堆外内存实现,而file模式使用类似SSD的高速缓存文件存储数据块。一般是使用堆外内存的方式。

四,hbase.hregion.memstore.flush.size
设置memestore大小,默认大小为128m。增大该值可以减少hfile文件的生成。但是会增加占用的内存 在内存大的情况下 可以调大该值。

五,hbase.hstore.blockingStoreFiles
默认值为10,如果任何一个store中hfile的文件大于这个值,则阻塞flush memstore操作,先进行一个compaction。这期间阻塞flush操作直到compaction完成或者超过hbase.hstore.blockingWaitTime(默认90s)配置的时间。在延时过程中将会继续写memstore,memstore可能会不断增大超过阈(六,mem store.flush.size* hbase.hregion.memstore.block.multiplier)导致memestore的写操作被阻塞,compation完成后就可能造成大量的数据写入,影响系统的性能。为了防止memstor的flush操作被阻塞,特别是写多都少的情况下可以提高该值。线上环境中一般设为100
六,hbase.hregion.memstore.block.multiplier
指单个MemStore大小超过本身大小的一个倍数时 就会阻止往memstore的写入操作。
可以适当调大该值避免memstore的写入被阻塞 但是要根据内存情况决定

compaction触发的情况大约有3种
一、在memestore flush后 会进行检测
二、后台线程CompactionChecker定期触发
hbase.server.thread.wakefrequencyhbase.server.compactchecker.interval.multiplier= 101000s
这个主要适用于在没有写请求时的compact检测 大约为2小时46分钟40秒
三、通过shell或者api进行触发

七,hbase.hstore.compaction.min
一次minor compaction最少合并的HFile数量,默认值 3。表示至少有3个符合条件的HFile,minor compaction才会启动。一般情况下不建议调整该参数。
如果要调整,不建议调小该参数,这样会带来更频繁的压缩,在写多读少的情况下,可以适当提高该参数减少compaction过程的发生

八,hbase.hstore.compaction.max
单次minor compaction 最大合并的文件个数 默认为10.
选择规则:hbase会将队列中的hfile按照年龄排序(old->young),优先选取年龄大的hfile文件。
扫描停止的条件:
当前已选文件大小<比当前文件更新的所有文件的大小总和*ratio (hbase.hstore.compaction.ratio默认1.2)
当前所剩候选文件数<=hbase.store.compaction.min(默认为3)
还有两个参数影响hfile文件的选取
hbase.hstore.compaction.min.size 小于这个参数的文件一定会被添加的合并队列中
hbase.hstore.compaction.max.size 大于这个参数的文件一定不会添加到合并队列中

九,hbase.regionserver.thread.compaction.large
默认值为1,regionserver做Major Compaction时线程池里线程数目。

十,hbase.regionserver.thread.compaction.small
默认值为1,regionserver做Minor Compaction时线程池里线程数目

HBase实现中有一个专门的线程CompactSplitThead负责接收compact请求以及split请求,而且为了能够独立处理这些请求,这个线程内部构造了多个线程池:largeCompactions、smallCompactions以及splits等,其中splits线程池负责处理所有的split请求,largeCompactions和smallCompaction负责处理所有的compaction请求,其中前者用来处理大规模compaction,后者处理小规模compaction。这里需要明白三点:

  1. 上述设计目的是为了能够将请求独立处理,提供系统的处理性能。
  2. 哪些compaction应该分配给largeCompactions处理,哪些应该分配给smallCompactions处理?是不是Major Compaction就应该交给largeCompactions线程池处理?不对。这里有个分配原则:待compact的文件总大小如果大于值throttlePoint(可以通过参数hbase.regionserver.thread.compaction.throttle配置,默认为2.5G),分配给largeCompactions处理,否则分配给smallCompactions处理。
  3. largeCompactions线程池和smallCompactions线程池默认都只有一个线程,用户可以通过参数hbase.regionserver.thread.compaction.large和hbase.regionserver.thread.compaction.small
    进行配置

十一,hbase.hregion.majorcompaction
Major compaction周期性时间间隔,默认七天执行一次。设置为 0 时表示禁用自动触发major compaction。因为Major compaction会合并所有 hfile文件,compaction过程持续时间长消耗资源多。所以一般会关闭自动触发 改为在系统不繁忙时进行手动触发。

十二, hbase.regionserver.global.memstore.upperLimit
配置一台regionserver所有memstore占整个堆的最大比例,这个参数的默认值为0.4
regionServer中所有memstore的大小,超过该大小会触发flush到磁盘的操作 而且regionserver级别的flush会阻塞客户端读写,调大该值可能造成regionserver堆内存不够用要根据实际情况合理按排
当然hbase.regionserver.global.memstore.upperLimit和hfile.block.cache.size的和不能大于0.8,Memstore+BlockCache的内存占比不能超过0.8(即80%),否则就会报错。注意必须留20%的机动空间.
十三,hbase.regionserver.global.memstore.lowerLimit
默认值为0.95,当memstore大小占内存比例达到 堆内存hbase.regionserver.global.memstore.upperLimithbase.regionserver.global.memstore.lowerLimit 时会进行一个局部的flush操作(选择一个region进行flush) 算是避免发生整个regionserver 发生flush的一种保护机制。 如果regionserver中频繁发生这个局部flush操作,那么有必要减少memstore的大小 或者适当提高upperLimit/lowerLimit 这两个值

何时split?
hbase调优参数整理

不同版本检验阈值的方法是不同的
ConstantSizeRegionSplitPolicy和IncreasingToUpperBoundRegionSplitPolicy 。
0.94版本中前者是默认算法,0.98版本后者是默认算法
ConstantSizeRegionSplitPolicy : 系统会遍历region所有store的文件大小,如果有文件大小 > hbase.hregion.max.filesize,就会触发切分操作。
IncreasingToUpperBoundRegionSplitPolicy:0.98版本 的默认策略则是store大小大于一个变化的阀值就允许split。计算公式为
region split的计算公式是:regioncount^3 * 128M * 2,当某个store达到该size的时候进行split
Math.min(getDesiredMaxFileSize(), this.initialSize * tableRegionsCount * tableRegionsCount * tableRegionsCount)

// getDesiredMaxFileSize() 这个值是hbase.hregion.max.filesize参数值,10GB
// this.initialSize值为2 * hbase.hregion.memstore.flush.size,256MB
// 最终是取Math.min(10G, 256 * regioncount^3)1
第一次split:1^3 * 256 = 256MB
第二次split:2^3 * 256 = 2048MB
第三次split:3^3 * 256 = 6912MB
第四次split:4^3 * 256 = 16384MB > 10GB,因此取较小的值10GB
后面每次split的size都是10GB了

十四,hbase.hregion.max.filecsize
hfile存储数据是按column family存储的,也就是任何一个列蔟存储值大于这个参数,都会发生hbase的split,默认大小为10G。
当hbase.hregion.max.filesize比较小时,触发split的机率更大,系统的整体访问服务会出现不稳定现象。
当hbase.hregion.max.filesize比较大时,由于长期得不到split,因此同一个region内发生多次compaction的机会增加了。这样会降低系统的性能、稳定性,因此平均吞吐量会受到一些影响而下降。

十五,hbase.zookeeper.session.timeout
默认三分钟,RegionServer与Zookeeper间的连接超时时间。当超时时间到后,ReigonServer会被Zookeeper从RS集群清单中移除,HMaster收到移除通知后,会对这台server负责的regions重新分配,让其他存活的RegionServer接管。
生产环境中regionserver的内存都会配置的比较大,regionserver在jvm做一次内存大回收时,时间也会变长,很有可能这个时间超过zookeeper.session.timeout时间,导致regionserver在jvm回收内存的时候,zookeeper误以为regionserver挂掉而将regionserver摘除。该值还是不要配的过大,首先地java已支持cms方式回收内存,每次内存回收的时间不是太长,并且生产环境中,不允许过长时间的服务中断,配置大了,容易造成一个regionserver的服务真出现异常时,zookeeper不会切除该regionserver,使得很多请求失败。

十六,hbase.regionserver.handler.count
RegionServer能够处理的IO请求线程数。默认是10.对于io频繁,每秒处理事务量要求比较高的情况下,可以设置的相对大些.通常都调到100~200之间,提高regionserver性能

十七.hbase.rpc.timeout
默认为60s,该参数表示一次RPC请求的超时时间。如果某次RPC时间超过该值,客户端就会主动关闭socket。

有时间会继续往下整理

hbse部分参数的整理。整理不易,不是随随便便的东拼西凑。如有错误欢迎指正。