原始采集数据采用Hbase进行存储。 实时采集数据流量很大,在入库的时候,有时候会发生阻塞。?
测试环境正常,生产环境下,时不时出现HRegionServer挂掉的情况, 而HMaster正常。 重启Hbase之后,短时间内恢复正常,然而一段时间之后,再次出现RegionServer挂掉的情况。 因此,我们决定对此故障进行深入排查,找出故障原因。?
从日志的异常记录来看, region-server日志中存在大量WAL异常(敏感信息已加码)
RegionServer挂掉以及JVM因GC暂停
从上述异常日志,我们可以故障原因推理。 因为某些原因导致GC(垃圾回收机制)花费时间过长, 进而JVM被暂停了。因此该节点不能够发送心跳给Zookeeper, Zookeeper将该节点标记为dead server。 启动容错机制,将状态记录在WAL中, 由其他节点代替该节点进行工作。?
在该节点GC完毕,恢复正常,请求Zookeeper重新将该节点加入集群。 然后超过timeout阈值,导致WAL无法被找到,恢复失败。 同理,直至所有节点都被Zookeeper标记为异常节点,导致整个集群的region server都无法工作。?
导致GC时间过长的原因有很多, 例如?
1. ZooKeeper内存分配不足,尤其是大量数据导入的时候?
2. 其他程序存在内存溢出bug?
3. CPU消耗过大
4. 节点失效timeout阈值过短
经过逐步排查,我们定位故障原因为第4点,timeout阈值不足。?
我们使用的是Hbase自带的ZooKeeper, 因此需要修改hbase-site.xml文件来配置timout值。
修改 zookeeper.session.timeout 为 100000 ms, 默认为 90000 ms
修改hbase.zookeeper.property.tickTime 为 6000 ms, 默认为 2000ms
注:?
如果timeout < tickTime * 2, 则实际timeout 为 tickTime * 2
如果timeout > tickTime * 20, 则实际timeout 为 tickTime * 20?
因此,我们需要注意?zookeeper.session.timeout 和 tickTime 之前的关系。?