问题的错误堆栈如下面所示:
java.lang.RuntimeException:
org.apache.hadoop.hbase.client.ScannerTimeoutException: 76745ms passed
since the last invocation, timeout is currently set to 60000
at
org.apache.hadoop.hbase.client.AbstractClientScanner$1.hasNext(AbstractClientScanner.java:97)
~[hbase-client-1.1.2.jar:1.1.2]
at
com.mogujie.fulldump.task.HBaseUtil.scanTable(HBaseUtil.java:109)
~[fulldump-indexbuildingcomponent-1.0-SNAPSHOT.jar:na]
at
com.mogujie.fulldump.task.HbaseScanner$Task.run(HbaseScanner.java:114)
[fulldump-indexbuildingcomponent-1.0-SNAPSHOT.jar:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
业务方报告超时错误后,我们按惯常的思路对服务端进行了排查,包括对更改表配置,对表数据进行major
compact *** 作等等,但是,经过对集群及表结构的一阵调整之后,超时错误仍然存在。解决问题的最好出发点就是分析源码,看看问题出在哪里,于是决定阅
读源码,找到错误的根节点。
从上面的异常可以看出错误出现在org.apache.hadoop.hbase.client.ScannerTimeoutException中,进入源码看看这个错误在哪里被打印。
在客户端的ClientScanner类的loadcache方法,我们找到了错误输出的地方,代码片段如下所示:
在上面的代码中,lastNext是前一次调用loadcache时的
系统时间,scannerTimeout是用户设置的超时时间。每次进入loadcache函数的时候,都会将当前的时间与前两者之和做对比,如果当前时
间大于了两者之和,则会报出Timeout错误。好啦,错误的原因已经知道了,解决方法就是增大scannerTimeout。scannerTimeout是由hbase.client.scanner.timeout.period控制的,默认值是60s,我们将上述配置增大到120s之后,问题解决,不再发生超时错误。
这个问题深入思考一下,为什么会有这么一个错误。loadcache的
作用是将服务端的数据缓存到本地,客户端中维护一个LinkedList<Result>类型的变量cache用于缓存从服务端region
中拉下的数据。客户端的scanner迭代时调用的next实际上是从这个cache中取的数据,直到cache中的数据被消费空,此时,会重新调用
loadcache开始新一轮从服务端拉取数据。
加大zookeeper会话超时时间,编辑hbase-site.xml文件,添加下面的属性
使用top命令查看regionserver是否有充足的cpu资源,mapreduce会占用很多cpu,可以减少mapreduce任务数
使用vmstat 1 命令查看si so两个swap列,确认没有发生交换,1代表每秒打印一次
使用jstat -gcutil pid 1000 查看fgct列,确认regionserver没有发生长时间gc暂停,如果gc时间超过zookeeper的连接最大超时时间则会导致hbase挂掉
hbase中和GC相关的参数
修改后
RegionServer 由于 ZooKeeper session expired 而退出,头疼了很久,总结可能的原因:
zookeeper的maxSessionTimeout默认值导致hbase regionserver超时
在hbase中经常会遇到regionserver挂掉的情况,查看日志会看到这样的错误信息
说明与zookeeper的连接的session超时了,可是在hbase-site.xml中设置了zookeeper的超时时间为2分钟,原来
zookeeper中自带两个参数设置了session的超时时间,在启动时日志中会显示
而minSessionTimeout 和maxSessionTimeout 是用下面的方式算出来的
Session
Session 默认情况,tickTime=2sec,那么minSessionTimeout 和 maxSessionTimeout 分别是4sec和40sec
所以在hbase中设置超时时间是没用的,必须修改zookeeper自身的maxSessionTimeout为120000,才能真正起到加长zookeeper的session超时时间的作用
昨天用HBase存数据的时候出了点小问题,程序放在服务器上,运行几分钟之后就开始报错:
而这个问题在我自己的电脑上测试时从未遇到过,查了些资料,先放解决办法:
在 conf/hbase-site.xml 中添加如下配置(每个节点都添加)
即设置超时时间为60s
参考:
hbase thrift 写数据报错
Stack Overflow——How to prevent errno 32 broken pipe?
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)