【甘道夫】HBase随机宕机事件处理 & JVM GC回顾

一、引言

本文记录了困扰团队两周的HBase随机宕机事件的解决方案,并回顾了JVM GC调优基础知识,供各位参考。


欢迎转载,请注明出处:

http://blog.csdn.net/u010967382/article/details/42394031




二、实验环境

16台虚拟机,每台4G内存,1核CPU,400G硬盘

Ubuntu 14.04 LTS (GNU/Linux 3.13.0-29-generic x86_64)

CDH5.2.0套装(包括相应版本的Hadoop,HIVE,Hbase,Mahout,Sqoop,Zookeeper等)

Java  1.7.0_60  64-Bit Server




三、异常现场

在以上实验环境中执行计算任务,计算任务涉及HIVE、Mahout、Hbase bulkload、MapReduce,工作流驱动通过Shell脚本控制,整个任务执行过程涉及基础行为数据160万条,业务数据40万条。

多次执行任务过程中反复随机出现以下各类异常,仅用文字描述,就不拷贝异常现场了,大家各自对号入座:

1.Hbase的Regionserver进程随机挂掉(该异常几乎每次都发生,只是挂掉的Regionser节点不同)

2.HMaster进程随机挂掉

3.主备Namenode节点随机挂掉

4.Zookeeper节点随机挂掉

5.Zookeeper连接超时

6.JVM GC睡眠时间过长

7.datanode写入超时

等等

通过调研分析和调试,发现问题解决需从以下几个方面着手:

1.Hbase的ZK连接超时相关参数调优:默认的ZK超时设置太短,一旦发生FULL GC,极其容易导致ZK连接超时;

2.Hbase的JVM GC相关参数调优:可以通过GC调优获得更好的GC性能,减少单次GC的时间和FULL GC频率;

3.ZK Server调优:这里指的是ZK的服务端调优,ZK客户端(比如Hbase的客户端)的ZK超时参数必须在服务端超时参数的范围内,否则ZK客户端设置的超时参数起不到效果;

4.HDFS读写数据相关参数需调优;

5.YARN针对各个节点分配资源参数调整:YARN需根据真实节点配置分配资源,之前的YARN配置为每个节点分配的资源都远大于真实虚拟机的硬件资源;

6.集群规划需优化:之前的集群规划中,为了充分利用虚拟机资源,NameNode、NodeManager、DataNode,RegionServer会混用同一个节点,这样会导致这些关键的枢纽节点通信和内存压力过大,从而在计算压力较大时容易发生异常。正确的做法是将枢纽节点(NameNode,ResourceManager,HMaster)和数据+计算节点分开。




四、为了解决该问题而实施的各类配置及集群调整



HBase



hbase-site.xml

<property>

<name>zookeeper.session.timeout</name>

<value>300000</value>

</property>

<property>

<name>hbase.zookeeper.property.tickTime</name>

<value>60000</value>

</property>

<property>

<name>hbase.hregion.memstroe.mslab.enable</name>

<value>true</value>

</property>

<property>

<name>hbase.zookeeper.property.maxClientCnxns</name>

<value>10000</value>

</property>

<property>

<name>hbase.client.scanner.timeout.period</name>

<value>240000</value>

</property>

<property>

<name>hbase.rpc.timeout</name>

<value>280000</value>

</property>

<property>

<name>hbase.hregion.max.filesize</name>

<value>107374182400</value>

</property>

<property>

<name>hbase.regionserver.handler.count</name>

<value>100</value>

</property>

<property>

<name>dfs.client.socket-timeout</name>

<value>300000</value>

<description>Down the DFS timeout from 60 to 10 seconds.</description>

</property>


hbase-env.sh

export HBASE_HEAPSIZE=2048M

export HBASE_HOME=/home/fulong/Hbase/hbase-0.98.6-cdh5.2.0

export HBASE_LOG_DIR=${HBASE_HOME}/logs

export HBASE_OPTS="-server -Xms1g -Xmx1g -XX:NewRatio=2 -XX:PermSize=128m -XX:MaxPermSize=128m -verbose:gc -Xloggc:$HBASE_HOME/logs/hbasegc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled
-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HBASE_HOME/logs"



zookeeper



zoo.cfg

syncLimit=10

#New in 3.3.0: the maximum session timeout in milliseconds that the server will allow the client to negotiate. Defaults to 20 times the tickTime.

maxSessionTimeout=300000

# the directory where the snapshot is stored.

# do not use /tmp for storage, /tmp here is just

# example sakes.

dataDir=/home/fulong/Zookeeper/CDH/zookdata

# the port at which the clients will connect

clientPort=2181


修改以下两个文件是为了跟踪ZK日志,ZK的默认日志查看不方便。

log4j.properties

zookeeper.root.logger=INFO,CONSOLE,ROLLINGFILE

zookeeper.console.threshold=INFO

zookeeper.log.dir=/home/fulong/Zookeeper/CDH/zooklogs

zookeeper.log.file=zookeeper.log

zookeeper.log.threshold=DEBUG

zookeeper.tracelog.dir=/home/fulong/Zookeeper/CDH/zooklogs

zookeeper.tracelog.file=zookeeper_trace.log

log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender

log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}

log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}

# Max log file size of 10MB

log4j.appender.ROLLINGFILE.MaxFileSize=50MB


zkEnv.sh

if [ "x${ZOO_LOG4J_PROP}" = "x" ]

then

ZOO_LOG4J_PROP="INFO,CONSOLE,ROLLINGFILE"

fi

备注:修改完以上两个文件后,并没有如愿的见到ZK的Log4j日志文件,原因待进一步调研。



HDFS



hdfs-site.xml

<property>

<name>dfs.datanode.socket.write.timeout</name>

<value>600000</value>

</property>

<property>

<name>dfs.client.socket-timeout</name>

<value>300000</value>

</property>

<property>

<name>dfs.datanode.max.xcievers</name>

<value>4096</value>

</property>



YARN



yarn-site.xml

<property>

<name>yarn.scheduler.minimum-allocation-mb</name>

<value>512</value>

</property>

<property>

<name>yarn.scheduler.fair.user-as-default-queue</name>

<value>false</value>

</property>

<property>

<name>yarn.resourcemanager.zk-timeout-ms</name>

<value>120000</value>

</property>

<property>

<name>yarn.nodemanager.resource.memory-mb</name>

<value>3072</value>

</property>

<property>

<name>yarn.scheduler.minimum-allocation-mb</name>

<value>128</value>

</property>

<property>

<name>yarn.scheduler.maximum-allocation-mb</name>

<value>3072</value>

</property>

<property>

<name>yarn.nodemanager.resource.cpu-vcores</name>

<value>1</value>

</property>

<property>

<name>yarn.scheduler.maximum-allocation-vcores</name>

<value>1</value>

</property>

<property>

<name>yarn.nodemanager.container-monitor.interval-ms</name>

<value>300000</value>

</property>



集群调整



NN Active, NN Standby, RM Active, RM Standby 所在节点均不运行DN,NM,RS

DN、NM、RS所在节点一一对应。

调整过后的布局:


说明:如果遇到类似问题,可以重点参考以上配置项,但具体数值请根据具体情况具体分析




五、补充回顾--JVM GC

调优过程中GC问题十分明显,未调优之前,频繁出现3~6min的Full GC时间,调优过后,GC时间能控制在20s以内。

GC调优对于Hadoop集群十分重要,是必须掌握的基础知识,在此简单记录。

完整知识叙述请参见:

英文原文:http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/

译文地址:http://www.importnew.com/1993.html

以及Oracle网站上的相关说明:

http://www.oracle.com/technetwork/java/javase/tech/exactoptions-jsp-141536.html

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140228.html

以下仅仅描述最重要的基础知识:


每个JVM主要内存区域分为两部分:Permanent Space 和 Heap Space

Permanent即持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大。

Heap={Old+NEW={Eden,Survivor 0 ,Survivor 1}},Old即老年代(Old
Generation),New即年轻代(Young Generation)。年轻代(Young Generation)用来保存那些第一次被创建的对象,它进一步被分为三个空间:一个伊甸园空间(Eden
),两个幸存者空间(Survivor )。老年代和年轻代的划分对垃圾收集影响比较大。

基本的执行顺序如下:

  1. 绝大多数刚刚被创建的对象会存放在伊甸园(Eden )空间。
  2. 在伊甸园(Eden )空间执行了第一次GC之后,存活的对象被移动到其中一个幸存者空间。
  3. 此后,在伊甸园空间执行GC之后,存活的对象会被堆积在同一个幸存者空间。
  4. 当一个幸存者空间饱和,还在存活的对象会被移动到另一个幸存者空间。之后会清空已经饱和的那个幸存者空间。
  5. 在以上的步骤中重复几次依然存活的对象,就会被移动到老年代。

截止目前版本,Java可配置的垃圾收集器有5种类型:

  1. Serial GC
  2. Parallel GC
  3. Parallel Old GC (Parallel Compacting GC)
  4. Concurrent Mark & Sweep GC  (or “CMS”)
  5. Garbage First (G1) GC

其中用得较多比较成熟的是CMS。

我们可以通过各种工具来监控JVM GC情况,比较简单直观的是jstat。比如我们要监控NameNode的GC情况,可以先用jps查看到进程号,然后通过jstat查看gc情况:

jstat -gcutil后面跟的参数是JVM进程号,1s是数据刷新时间。命令输出的每一列依次是:幸存者0的空间占用比例,幸存者1的空间占用比例,伊甸园空间的占用比例,老年代空间的占用比例,持久代空间的占用比例,年轻代(S0+S1+E)发生GC的次数,年轻代发生GC的总时间(秒为单位),FULL GC发生的次数,FULL GC发生的总时间(秒为单位),GC消耗的总时间(秒为单位)。

最后附上我们本次调优hbase设置的JVM参数:

-server                      //开启java服务器模式

-Xms1g                    //最小最大堆内存

-Xmx1g

-XX:NewRatio=2        //老年代空间:年轻代空间=2

-XX:PermSize=128m        //初始和最大持久代空间,感觉可以进一步缩减,目前观察持久代空间使用没超过30%

-XX:MaxPermSize=128m

-Xloggc:$HBASE_HOME/logs/hbasegc.log   //开启gc日志功能,便于调试,基本不会影响性能

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-XX:+UseParNewGC                                         //开启CMS垃圾回收期

-XX:+CMSParallelRemarkEnabled

-XX:+UseConcMarkSweepGC

-XX:CMSInitiatingOccupancyFraction=75

时间: 2025-01-01 14:28:27

【甘道夫】HBase随机宕机事件处理 & JVM GC回顾的相关文章

【甘道夫】Eclipse+Maven搭建HBase开发环境及HBaseDAO代码示例

环境: Win764bit Eclipse Version: Kepler Service Release 1 java version "1.7.0_40" 第一步:Eclipse中新建Maven项目,编辑pom.xml并更新下载jar包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&qu

【甘道夫】HBase基本数据操作详解【完整版,绝对精品】

引言 之前详细写了一篇HBase过滤器的文章,今天把基础的表和数据相关操作补上. 本文档参考最新(截止2014年7月16日)的官方Ref Guide.Developer API编写. 所有代码均基于"hbase 0.96.2-hadoop2"版本编写,均实测通过. 欢迎转载,请注明来源: http://blog.csdn.net/u010967382/article/details/37878701 概述 对于建表,和RDBMS类似,HBase也有namespace的概念,可以指定表空

【甘道夫】HBase开发环境搭建过程中可能遇到的异常:No FileSystem for scheme: hdfs

异常: 2014-02-24 12:15:48,507 WARN  [Thread-2] util.DynamicClassLoader (DynamicClassLoader.java:<init>(106)) - Failed to identify the fs of dir hdfs://fulonghadoop/hbase/lib, ignored java.io.IOException: No FileSystem for scheme: hdfs 解决: 在pom文件中加入: &

【甘道夫】HBase(0.96以上版本)过滤器Filter详解及实例代码

说明: 本文参考官方Ref Guide,Developer API和众多博客,并结合实测代码编写,详细总结HBase的Filter功能,并附上每类Filter的相应代码实现. 本文尽量遵从Ref Guide中"9.4. Client Request Filters"的行文顺序,便于读者对比查看,但内容比官方文档更加详实. 欢迎转载,请注明来源: http://blog.csdn.net/u010967382/article/details/37653177 目录: 引言 -- 参数基础

【甘道夫】Hadoop2.2.0环境使用Sqoop-1.4.4将Oracle11g数据导入HBase0.96,并自动生成组合行键

目的: 使用Sqoop将Oracle中的数据导入到HBase中,并自动生成组合行键! 环境: Hadoop2.2.0 Hbase0.96 sqoop-1.4.4.bin__hadoop-2.0.4-alpha.tar.gz Oracle11g jdk1.7 Ubuntu14 Server 这里关于环境吐槽一句: 最新版本的Sqoop1.99.3功能太弱,只支持导入数据到HDFS,没有别的任何选项,太土了!(如有不同意见欢迎讨论给出解决方案) 命令: sqoop import --connect

【甘道夫】Hadoop2.2.0 NN HA详细配置+Client透明性试验【完整版】

引言: 前面转载过一篇团队兄弟[伊利丹]写的NN HA实验记录,我也基于他的环境实验了NN HA对于Client的透明性. 本篇文章记录的是亲自配置NN HA的详细全过程,以及全面测试HA对客户端访问透明性的全过程,希望对大家有帮助. 实验环境: Hadoop2.2.0的4节点集群,ZK节点3个(ZK节点数最好为奇数个),hosts文件和各节点角色分配如下: hosts: 192.168.66.91 master 192.168.66.92 slave1 192.168.66.93 slave2

【甘道夫】Sqoop1.99.3基础操作--导入Oracle的数据到HDFS

第一步:进入客户端Shell [email protected]:~$ sqoop.sh client Sqoop home directory: /home/fulong/Sqoop/sqoop-1.99.3-bin-hadoop200 Sqoop Shell: Type 'help' or '\h' for help. sqoop:000> set server --host FBI003 --port 12000 --webapp sqoop Server is set successfu

【甘道夫】Hadoop2.4.1尝鲜部署+完整版配置文件

引言 转眼间,Hadoop的stable版本已经升级到2.4.1了,社区的力量真是强大!3.0啥时候release呢? 今天做了个调研,尝鲜了一下2.4.1版本的分布式部署,包括NN HA(目前已经部署好了2.2.0的NN HA,ZK和ZKFC用现成的),顺便也结合官方文档 http://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-common/ClusterSetup.html  梳理.补全了关键的配置文件属性,将同类属性归

【甘道夫】使用sqoop-1.4.4.bin__hadoop-2.0.4-alpha将Oracle11g数据导入HBase0.96

环境: Hadoop2.2.0 Hbase0.96 sqoop-1.4.4.bin__hadoop-2.0.4-alpha.tar.gz Oracle11g jdk1.7 Ubuntu14 Server 这里关于环境吐槽一句: 最新版本的Sqoop1.99.3功能太弱,只支持导入数据到HDFS,没有别的任何选项,太土了!(如有不同意见欢迎讨论给出解决方案) 命令: sqoop import --connect jdbc:oracle:thin:@192.168.0.147:1521:ORCLGB