HBase 1.2.X,Zookeeper,3.4.X
HBase的regionserver进程挂掉,查看日志,发现如下报错:
FATAL [main-EventThread] regionserver.HRegionServer: ABORTING region server
org.apache.zookeeper.KeeperException$SessionExpiredException: KeeperErrorCode = Session expired
查看regionserver的日志,发现了问题的实质,即regionserver的full gc导致zookeeper的节点连接超时,session expired,接下来regionserver进程就被aborted了
此处先进行一下科普,hbase的session timeout的用途以及如何被配置的:
当hbase的regionserver节点down掉后,zookeeper会通过timeout发现hbase的regionserver出现问题,并将此问题反馈给hbase的master,master将该regionserver的region在其他regionserver上上线,对外提供服务,并对region进行balance操作。
上述问题都需要在默认配置的基础上进行相应的延长,默认情况下该配置项在hbase-site.xml中的zookeeper.session.timeout配置,默认是90000ms(1.X版本)
但是某些情况下配置不起作用,此处划重点,zookeeper client在初始化时忽略此配置项,服务器强制加载该timeout在[minSessionTimeout, maxSessionTimeout]之间,这两个配置项在zookeeper的zoo.cfg中配置,如果未配置,默认是[2 * tickTime and 20 * tickTime],tickTime默认是2s,它也是管理心跳时间间隔的字段,所以zookeeper的session timeout 是在[4,40]秒之间,hbase-site.xml中配置的zookeeper.session.timeout默认情况下只有在此范围内才会起作用,否则会取maxSessionTimeout的40s作为timeout时间
那么问题来了,怎么才能修改timeout使之超过40s呢?部分小伙伴可能发现了最直接简单粗暴的方式就是修改tickTime,使之变大,但是在这里不建议这么做,因为这样同样会改变zookeeper的心跳时间,那还能怎么办呢?呵呵,看源码:
minSessionTimeout 和maxSessionTimeout 是用下面的方式算出来的
public int getMinSessionTimeout()
{ return minSessionTimeout == -1 ? tickTime * 2 : minSessionTimeout; }
public int getMaxSessionTimeout()
{ return maxSessionTimeout == -1 ? tickTime * 20 : maxSessionTimeout; }
从上面可以看到,如果maxSessionTimeout有值,则会优先使用该值,所以修改zookeeper自身的maxSessionTimeout为600000,才能真正起到加长zookeeper的session超时时间的作用。实践再次说明看源码的重要性。
当然,也不建议将zookeeper.session.timeout在[minSessionTimeout, maxSessionTimeout]区间内改的过大,因为如果regionserver真的挂掉了,那么会耽误到zookeeper发现异常并通知master进行failover,进而耽误hbase的可用性,所以大多数情况下默认的90秒已经够用了,如果还会出现类似的情况,那么要么改善网络环境,要么优化hbase jvm的gc策略,这个比修改超时时间更能彻底的解决问题。
下面备注下hbase-site.xml修改相关配置的样例:
配置“hbase.regionserver.restart.on.zk.expire” 为true。 这样子,遇到ZooKeeper session expired , regionserver将选择 restart 而不是 abort
具体的配置是,在hbase-site.xml中加入
HBase passes this to the zk quorum as suggested maximum time for a
session. See http://hadoop.apache.org/zooke ... sions
“The client sends a requested timeout, the server responds with the
timeout that it can give the client. The current implementation
requires that the timeout be a minimum of 2 times the tickTime
(as set in the server configuration) and a maximum of 20 times
the tickTime.” Set the zk ticktime with hbase.zookeeper.property.tickTime.
In milliseconds.
Zookeeper session expired will force regionserver exit.
Enable this will make the regionserver restart.