JVM讲解
新生代
对象刚创建过来存储的地方,新生代空间大小一般为128~512M,数据在新生代停留时间过长,就会转移到老生代中
老年代
存活时间比较长的,主要的应用程序,老生代可达几GB,当不用了,gc会回收的
永久代(jdk1.8元空间)
经历过几次回收后,还存在的
内存分配:
-Xmx:表示最大可用内存
-Xms:表示初始分配内存
-Xmn:年轻代堆内存分配
+UseParNewGC:表示年轻代内存回收策略采用并发收集
+UseConcMarkSweepGC:表示年老代并发收集
+CMSInitiatingOccupancyFraction:当年老代对内存占用90%以上时,才开始做内存收集,而此时剩余的10%依然接受从年轻代迁移过来的对象,迁移过快,导致年老代heap 100%时,Full GC 即开始,才是会暂停所有的任务,直至Full GC完成。建议是设置为70
Memstore和Blockcache块缓存
HBase上Regionserver的内存分为两个部分,一部分作为Memstore,主要用来写;另外一部分
作为BlockCache,主要用于读。
写请求会先写入Memstore,Regionserver会给每个region提供一个Memstore,当Memstore
满128MB(hbase.hregion.memstore.flush.size)以后,会启动 flush刷新到磁盘。regionserver中所有的Memstore的总大小超过限制时(heapsize *hbase.regionserver.global.memstore.upperLimit(0.4)),会强行启动flush进程,从最大的Memstore开始flush直到低于限制。
读请求先到Memstore中查数据,查不到就到BlockCache中查,再查不到就会到磁盘上读,并把
读的结果放入BlockCache。由于BlockCache采用的是LRU策略,因此BlockCache达到上限(heapsize * hfile.block.cache.size(0.4) * 0.85)后,会启动淘汰机制,淘汰掉最老的一批数据。在注重读响应时间的应用场景下,可以将 BlockCache设置大些,Memstore设置小些,以加大缓存的命中率。
将Cache分级思想的好处在于:
首先,通过inMemory类型Cache,可以有选择地将in-memory的column families放到RegionServer内存中,例如Meta元数据信息;
通过区分Single和Multi类型Cache,可以防止由于Scan操作带来的Cache频繁颠簸,将最少使用的Block加入到淘汰算法中。
默认配置下,对于整个BlockCache的内存,又按照以下百分比分配给Single、Multi、InMemory使用:0.25、0.50和0.25。
其中InMemory队列用于保存HBase Meta表元数据信息,因此如果将数据量很大的用户表设置为
InMemory的话,可能会导致Meta表缓存失效,进而对整个集群的性能产生影响。
本地MemStore缓存
有个对象被清除后,有个对象就被空出来一块,但是这个对象的大小不足以满足存储其他对象,把空出来的这个块附近的其他对象全部赶走,然后流出来一个大块,共新对象使用。但是消耗资源太大了
解决方案:
不填充坑,也不赶走对象,有合适的对象就放,能放下就放,不能放就等
配置参数:
hbase.hregion.memstore.mslab.enabled,默认为true
弊端:
一段时间很少生成对象,这些孔洞就一直在哪里留着,就导致孔洞的浪费
Compact和Split
HRegoin Server上的storefile文件是被后台线程监控的,以确保这些文件保持在可控状态。磁盘上的storefile的数量会随着越来越多的memstore被刷新而变等于越来越多——每次刷新都会生成一个storefile文件。当storefile数量满足一定条件时(可以通过配置参数类调整),会触发文件合并操作——minor compaction,将多个比较小的storefile合并成一个大的storefile文件,直到合并的文件大到超过单个文件配置允许的最大值时会触发一次region的自动分割,即regionsplit操作,将一个region平分成2个。
minor compaction,轻量级(频发的发生,一般就是关闭的。需要手动出发)
将符合条件的最早生成的几个storefile合并提前生成一个大的storefile文件,它不会删除被标记为“删除”的数据和过期的数据,并且执行过一次minor合并操作后还会有多个storefile文件,这个过程实际上是多路归并的过程。
major compaction,重量级(磁盘IO顿时增大,7天出发)
把所有的storefile合并成一个单一的storefile文件,在文件合并期间系统会删除标记为”删除”标记的数据和过期失效的数据,同时会block所有客户端对该操作所属的region的请求直到合并完毕,最后删除已合并的storefile文件。
将hbase.hregion.max.filesize值(默认10G,StoreFiled的最大值)设置稍微大些,比如100G,这样就不会触发自动拆分,然后在hbase空闲时刻,手动调用split进行拆分
启用SNAPPY压缩
参数:
HBase Master 的 Java 堆栈大小(字节)
● 线上配置:2G
HBase RegionServer 的 Java 堆栈大小(字节)
● 线上配置:32G
zookeeper.session.timeout
● 客户端与zk连接超时时间
● 线上配置:1200000(20min)
● 默认值:60000(1min)
hbase.security.authentication(暂时没用到)
● HBase集群安全认证机制,目前的版本只支持kerberos安全认证。
● 线上配置:kerberos
● 默认值:空
hbase.security.authorization(暂时没用到)
● HBase是否开启安全授权机制
● 线上配置: true
● 默认值: false
hbase.regionserver.kerberos.principal(暂时没用到)
● regionserver的kerberos认证的主体名称(由三部分组成:服务或用户名称、实例名称以及域名)
● 线上配置:hbase/_HOST@HADOOP.xxx.xxx.COM
● 默认:无
hbase.regionserver.keytab.file(暂时没用到)
● regionserver keytab文件路径
● 线上配置:/home/hadoop/etc/conf/hbase.keytab
● 默认值:无
hbase.master.kerberos.principal(暂时没用到)
● master的kerberos认证的主体名称(由三部分组成:服务或用户名称、实例名称以及域名)
● 线上配置:hbase/_HOST@HADOOP.xxx.xxx.COM
● 默认:无
hbase.master.keytab.file(暂时没用到)
● master keytab文件路径
● 线上配置:/home/hadoop/etc/conf/hbase.keytab
● 默认值:无
hbase.regionserver.handler.count
● regionserver处理IO请求的线程数
● 线上配置:150
● 默认配置:10
hbase.regionserver.global.memstore.upperLimit
● RegionServer进程进行flush触发条件:该节点上所有region的memstore之和达到upperLimit*heapsize,将所有的memstore刷新到磁盘中
● 线上配置:0.45
● 默认配置:0.4
hbase.regionserver.global.memstore.lowerLimit
● RegionServer进程触发flush的一个条件:该节点上所有region的memstore之和达到lowerLimit*heapsize,会选择一些占用内存比较大的MemStore阻塞写操作并进行flush,这是为了降低阻塞全部写操作flush带来的问题
● 线上配置:0.4
● 默认配置:0.35
hbase.client.write.buffer
● 客户端写buffer,设置autoFlush为false时,当客户端写满buffer才flush
● 线上配置:8388608(8M)
● 默认配置:2097152(2M)
hbase.hregion.max.filesize
● 单个ColumnFamily的region大小,若按照ConstantSizeRegionSplitPolicy策略,超过设置的该值则自动split
● 线上配置:107374182400(100G)
● 默认配置:21474836480(20G)
hbase.hregion.memstore.block.multiplier
● 超过memstore大小的倍数达到该值则block所有写入请求,自我保护,当一个Region的MemStore总量达到hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size(默认2*128M=256M)时,会阻塞这个region的写操作,并强制刷写到HFile。触发这个刷新只会发生在MemStore即将写满128M时put了一个巨大的记录的情况,这时会阻塞写操作,强制刷新成功才能继续写入。
● 线上配置:8(内存够大可以适当调大一些,出现这种情况需要客户端做调整)
● 默认配置:2
hbase.hregion.memstore.flush.size
● memstore大小,当达到该值则会flush到hfile中,这个是不阻塞写请求的
● 线上配置:104857600(100M)
● 默认值: 134217728(128M)
hbase.hregion.memstore.mslab.enabled
● 是否开启mslab方案,减少因内存碎片导致的Full GC,提高整体性能
● 线上配置:true
● 默认配置: true
hbase.regionserver.maxlogs
● regionserver的hlog数量
● 线上配置:128
● 默认配置:32
hbase.regionserver.hlog.blocksize
● hlog大小上限,达到该值则block,进行roll掉,当HLog达到最大值(hbase.regionserver.maxlogs * hbase.regionserver.hlog.blocksize 默认32*64M = 2G)时,也会触发MemStore的刷新,强制将更新固化到HFile中,避免在RegionServer crash时恢复时间过长。
● 线上配置:536870912(512M)
● 默认配置:hdfs配置的block大小
hbase.hstore.compaction.max
● 单次minor compact最多的文件个数
● 线上配置:30
● 默认配置:10
hbase.hstore.blockingStoreFiles
● 在任意 HStore 中有超过此数量的 HStoreFiles,则会阻止对此 HRegion 的更新,直到完成compact或直到超过为 ‘hbase.hstore.blockingWaitTime’ 指定的值。
● 线上配置:100(生产环境可以设置得很大)
● 默认配置: 7
hbase.hstore.blockingWaitTime
● block的等待时间
● 线上配置:90000(90s)
● 默认配置:90000(90s)
hbase.hregion.majorcompaction
● 触发major compact的周期
● 线上配置:0(关掉major compact)
● 默认配置:86400000(1d)
hbase.regionserver.thread.compaction.small
● small compact线程池的线程个数
● 线上配置:5
● 默认配置:1
hbase.rpc.timeout
● RPC请求timeout时间
● 线上配置:300000(5min)
● 默认配置:60000(10s)