HBase节点离线(如服务器崩溃)时Put等操作永久挂起问题咨询
老哥,你遇到的这个问题确实戳中了分布式存储HA设计的核心诉求——节点挂了之后请求应该自动Failover到可用节点,不会永久卡着。之所以出现这种情况,大概率是几个配置或者集群状态的细节没到位,咱们一步步捋:
1. 故障检测与Region重分配延迟
首先看你贴的日志:
(AsyncProcess.java:1777) - 剩余1个任务将在以下服务器上处理:[s1.mycompany.com,16020,1519065917510, s2.mycompany.com,16020,1519065918510, s3.mycompany.com,16020,1519065917410]
这说明客户端还在往已经离线的s2、s3发请求,集群还没完成这两个节点上Region的重分配。问题可能出在:
- Master故障检测阈值太高:HBase Master依赖ZooKeeper的会话超时来识别RegionServer离线,如果
zookeeper.session.timeout(默认180000ms)或者hbase.regionserver.restarted.timeout设得太大,Master会延迟很久才确认节点挂了,自然不会触发Region转移。 - Master负载过高:50节点的集群如果Master本身压力大(比如同时处理大量Region分裂、合并),会导致Region重分配的队列堆积,没法及时把离线节点的Region转移到在线节点。
2. 客户端重试策略配置不合理
AsyncProcess作为HBase客户端处理异步请求的核心,它的重试逻辑如果配置不当,会导致请求一直卡在重试离线节点:
- 检查客户端配置里的
hbase.client.retries.number:如果这个值设得过大(比如默认是35),加上hbase.client.pause(默认100ms)的指数退避,请求会持续重试很长时间,看起来就像永久挂起。 - 另外
hbase.client.max.per.region.tasks如果设得太高,会导致大量任务堆积在离线节点的Region上,进一步加剧挂起的情况。
3. Region副本数不足导致无可用节点
如果你的目标表的Region副本数(hbase.table.regions.replica.count)设置为1,那当s2、s3上的Region离线后,就没有其他可用副本能处理请求了——这种情况下HA根本没法生效,因为没有冗余节点可以Failover。正常HA场景下,表的副本数至少要设为2或3。
4. ZooKeeper集群状态异常
ZK是HBase集群的“大脑”,如果ZK出现延迟、脑裂或者节点故障,会导致Master无法准确感知RegionServer的离线状态,进而无法触发HA流程。可以检查ZK的日志,看看有没有会话超时、选举异常的报错。
快速排查与解决步骤
- 先调整客户端重试配置:把
hbase.client.retries.number降到10-20,hbase.client.pause设为500ms,避免请求无限制重试;同时设置hbase.client.max.total.tasks限制总任务数,防止堆积。 - 确认表的副本数:在HBase Shell里执行
describe '你的表名',查看REGION_REPLICA_COUNT的值,要是小于2,执行alter '你的表名', {NAME => '你的列族', REGION_REPLICA_COUNT => 2}来修改,然后触发Region重分配。 - 检查集群状态:在HBase Shell里执行
list_dead_servers,看看集群有没有识别到s2、s3离线;查看Master日志,搜索Region assignment相关的关键词,确认有没有分配超时或者报错。 - 验证ZK状态:用
zkCli.sh连接ZK,查看/hbase/rs节点下的内容,确认s2、s3的节点信息是否已经被移除。
内容的提问来源于stack exchange,提问作者AdamSkywalker
相关产品推荐
相关产品推荐

