原创

Hbase Region Server异常分析

背景介绍

3regionserver3zookeepermaster单节点(master2未启动),实时处理程序,实时向HBase表写数据,Hbase集群于hdfshive、调度系统公用,集群上每天凌晨0点至上午10点跑10小时左右的调度任务。

 

问题现象

Regionserver经常出现宕机事件

Master standby停机

 

推测原因&分析

1、compactionsplit过于频繁

blob.png

Hbase0.94以后hfile最大文件配置hbase.hregion.max.filesize=10G

Region大小与集群支持的总数据量大小有关,如果总量太小,单个region太大,不利于并行数据处理;如果集群需支持的总数据量比较大,region太小,则会导致region的个数过多,导致region的管理、split等成本过高;

我们一个RS配置的磁盘为16T数据量,数据replica=3,则一台RS可以存储5T数据量,如果每个region最大为10G,则最多500region

Hbase通过split 实现水平sharding,但是在split过程中旧region会下线,新region还会做compaction,中间有一段时间大量数据不能被读写,这对于online是不能忍受的。

如果要自己管理regionsplit,可再调大该值,并且在建表的时候规划好region数量和rowkey设计;进行region预建做到一定时间内,控制每个region的数据大小在一定的数据量之下。另外,一般在线服务的hbase集群都会弃用hbase的自动split,转而自己管理split。禁止自动split&compaction(默认7),在集群空闲期(白天)执行手动split(通过脚本实现)

blob.png


2、Hdfs压力过大,datanoderegionserver超负荷

由于集群运行各种任务,hdfs读写压力大,datanode的负载比较高,导致regionserverhdfs异常,宕机

2017-03-30 02:25:54,414 WARN org.apache.hadoop.hdfs.DFSClient: Slow ReadProcessor read fields took 65021ms (threshold=30000ms); ack: seqno: -2 reply: 0 reply: 1 downstreamAckTimeNanos: 0, targets: [DatanodeInfoWithStorage[192.168.2.62:50010,DS-a98bc32d-0b3a-4cf2-b17b-b1a24badb9b4,DISK],DatanodeInfoWithStorage[192.168.2.64:50010,DS-82640457-7b92-4347-b0a8-7405804117eb,DISK]]
2017-03-30 02:25:54,417 WARN org.apache.hadoop.hdfs.DFSClient: DFSOutputStream ResponseProcessor exception  for block BP-305404928-192.168.2.60-1477041256525:blk_1082088790_8349147java.io.IOException: Bad response ERROR for block BP-305404928-192.168.2.60-1477041256525:blk_1082088790_8349147 from datanode DatanodeInfoWithStorage[192.168.2.64:50010,DS-82640457-7b92-4347-b0a8-7405804117eb,DISK]      at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer$ResponseProcessor.run(DFSOutputStream.java:1022)2017-03-30 02:25:54,418 WARN org.apache.hadoop.hdfs.DFSClient: Error Recovery for block BP-305404928-192.168.2.60-1477041256525:blk_1082088790_8349147 in pipeline DatanodeInfoWithStorage[192.168.2.62:50010,DS-a98bc32d-0b3a-4cf2-b17b-b1a24badb9b4,DISK],DatanodeInfoWithStorage[192.168.2.64:50010,DS-82640457-7b92-4347-b0a8-7405804117eb,DISK]: bad datanode DatanodeInfoWithStorage[192.168.2.64:50010,DS-82640457-7b92-4347-b0a8-7405804117eb,DISK]

当前hbase运行模式(hbase.cluster.distributed)默认false为单机模式。应设置为true,开启分布式模式.

DataNode Java 堆栈大小(字节)为1G,建议2G.

HBase Master Java 配置选项 & HBase RegionServer Java 配置选项

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC 
-XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled

修改:

Master:
-Xms4g -Xmx4g -Xmn1g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
 -XX:CMSInitiatingOccupancyFraction=70 -XX:PermSize=128m 
-XX:MaxPermSize=128m 
Region Server:
-Xms20g -Xmx20g -Xmn4g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
 -XX:CMSInitiatingOccupancyFraction=70
-XX:PermSize=128m -XX:MaxPermSize=128m 
-XX:MaxDirectMemorySize=16G
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC
-XX:-OmitStackTraceInFastThrow 
-XX:+HeapDumpOnOutOfMemoryError


3、blockingStoreFiles设置不合理

日志中频繁出现”has too many store files;delaying flush up to 90000ms”

2017-03-25 03:48:07,940 WARN org.apache.hadoop.hbase.regionserver.MemStoreFlusher: Region f_acct_idtfno_map,430122197005187122A104727411600019,1481553873843.1611e051523f8955b80d7b8012ca4960. has too many store files; delaying flush up to 90000ms
2017-03-25 03:48:08,356 INFO org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher: Flushed, sequenceid=562745, memsize=130.9 M, hasBloomFilter=true, into tmp file hdfs://nameservice1/hbase/data/default/f_acct_idtfno_map/1f70d611178c72de82fa5493dbd0772b/.tmp/6e35b0fe71b34f23aa0694a471050f5a
2017-03-25 03:48:08,370 INFO org.apache.hadoop.hbase.regionserver.HStore: Added hdfs://nameservice1/hbase/data/default/f_acct_idtfno_map/1f70d611178c72de82fa5493dbd0772b/f/6e35b0fe71b34f23aa0694a471050f5a, entries=677274, sequenceid=562745, filesize=49.6 M
2017-03-25 03:48:08,372 INFO org.apache.hadoop.hbase.regionserver.HRegion: Finished memstore flush of ~130.90 MB/137260672, currentsize=11.55 MB/12110752 for region f_acct_idtfno_map,432426391218237A101248659100020,1481653983532.1f70d611178c72de82fa5493dbd0772b. in 2659ms, sequenceid=562745, compaction requested=true

Hbase配置hbase.hstore.blockingStoreFiles=10(默认)

如果任何一个storestorefile文件数大于该值,则在flush memstore前先进行split或者compact,同时把该region添加到flushQueue中,延时刷新,这期间会阻塞写操作知道compact完成或者超过hbase.hstore.blockingWaitTime(默认90s)

建议:为避免memstore不及时flush,该值需要上调,具体值可以在测试环境评估及压测后上线。

 

4、GC回收时Jvm不够

每天Jvm间隔一段时间就会停顿短则几秒,长可达20s,甚至30s,日志见下:

2017-03-30 02:24:11,370 INFO org.apache.hadoop.hbase.util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately 7478ms
No GCs detected
2017-03-30 02:21:12,805 WARN org.apache.hadoop.hbase.util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately 10286ms
GC pool 'ParNew' had collection(s): count=1 time=10466ms
2017-03-30 02:27:04,086 WARN org.apache.hadoop.hbase.util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately 23505ms
No GCs detected
2017-03-28 02:09:24,442 WARN org.apache.hadoop.hbase.util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately 39933ms
No GCs detected


查看Regionserverheapsize设置为32Ghfile.block.cache.size=0.4,使得block size=heapsize * hfile.block.cache.size *0.85=10.88G

由此可以block cache发生了CMS GC。目前使用的BlockCache优点是直接采用jvm提供的HashMap来管理Cache,简单可依赖;内存用多少占多少,JVM会帮你回收淘汰的BlOCK占用的内存。缺点更明显:

a.一个Block从被缓存至被淘汰,基本伴随着Heap中的位置从New区晋升到Old

b.晋升在Old区的Block被淘汰后,最终由CMS进行垃圾回收,随之带来的是Heap碎片 old 区域变大导致cms 时间过长。

c.因为碎片问题,随之而来的是GC时晋升失败的FullGC,我们的线上系统根据不同的业务特点,因为这个而发生FullGC的频率,有1天的,1周的,1月半年的都有。对于高频率的, 在运维上可以通过在半夜手工触发FullGC来缓解

d.如果缓存的速度比淘汰的速度快,很不幸现在的代码有OOM的风险(这个可以修改下代码避免)

 

Hbase0.94+提供了BucketCache,一方面可以降低regionserver heapsize的大小,降低cms发生的几率和减少时间;另一面可通过利用BucketCache增加二级缓存,来利用off heap cache,当然也可以将现有数据盘更换为SSD来做二级缓存。

Hbase-site.xml

<property>
  <name>hbase.bucketcache.ioengine</name>
  <value>offheap</value>
</property>
<property>
  <name>hbase.bucketcache.percentage.in.combinedcache</name>
  <value>0.8</value>
</property>
<property>
  <name>hbase.bucketcache.size</name>
  <value>16384</value>
</property>

 

增加读缓存后,也可以提高data block的命中率。当前集群regionserver缓存命中率平均<50%,截图见下:

blob.png

 

参考资料

http://hbase.apache.org/book.html#hbase_default_configurations

~阅读全文-人机检测~

微信公众号“Java精选”(w_z90110),专注Java技术干货分享!让你从此路人变大神!回复关键词领取资料:如Mysql、Hadoop、Dubbo、Spring Boot等,免费领取视频教程、资料文档和项目源码。微信搜索小程序“Java精选面试题”,内涵3000+道Java面试题!

涵盖:互联网那些事、算法与数据结构、SpringMVC、Spring boot、Spring Cloud、ElasticSearch、Linux、Mysql、Oracle等

评论

分享:

支付宝

微信