首页 / 资讯中心 / 文章详情

HBase建表报错PleaseHoldException:Master初始化卡住的排查与根因分析

HBase建表报错PleaseHoldException:Master初始化卡住的排查与根因分析 ★ FEATURED ARTICLE
1. 从一次建表卡壳说起这个报错到底在说什么如果你正在用 HBase Shell 敲下create test_table, cf结果终端回给你一句ERROR: org.apache.hadoop.hbase.PleaseHoldException: Master is initializing那你大概率正处在一个非常尴尬的阶段——集群看起来起来了进程也都在但就是什么表都建不了。这个报错字面意思是Master 正在初始化很多人第一反应是那我等一会儿不就行了结果等了十分钟、半小时甚至重启了集群报错依旧。问题就出在这个异常名字有很强的误导性它并不总是代表真的还在初始化。先把结论摆在前面PleaseHoldException是 HBase Master 在尚未完成初始化initialization或正处于状态切换如主备切换、region 分配、meta 恢复时对客户端请求返回的一种拒绝服务响应。它本质上是一个我还没准备好你先别急的信号。但触发它的场景远不止刚启动这一种这才是坑最多的地方。我见过太多人卡在这一步反复重启、反复格式化最后把好好的数据搞没了。这篇文章面向的是正在搭建或维护 HBase 集群的开发和运维同学尤其是那些第一次独立部署、或者在生产环境遇到主备切换后建表失败的人。我会把触发这个异常的几大类根因拆开讲清楚给出可复现的排查链路再补上我自己踩过的坑和验证过的处理手法。你不需要是 HBase 专家但需要能登机器、会看日志、敢敲命令。读完之后你应该能做到看到这个报错不再盲目重启而是能顺着一条清晰的路径定位到真正的原因。需要提前说明的是HBase 的版本差异对这个报错的表现影响很大1.x、2.x、3.x 在 Master 初始化流程、meta 表管理方式hbase:meta是否还在 ZooKeeper 里上都有变化。下面涉及具体路径和命令时我会尽量标注版本差异你对照自己的环境取用。2. Master 初始化到底在做什么先搞懂它为什么不肯干活要治这个病得先知道 Master 启动时那几分钟到底在忙什么。很多人把 HBase Master 想象成一个开关打开就能用其实它启动过程是一串有严格顺序的状态机。只有走完这套流程Master 才会从初始化中切到运行中才开始接受建表、删表、改表这类 DDL 请求。2.1 Master 启动的状态流转一个 HBase Master 从进程拉起到真正可用大致经历这么几个阶段进程启动与配置加载读取hbase-site.xml、hbase-env.sh确定hbase.rootdir、hbase.zookeeper.quorum等关键参数。连接 ZooKeeperMaster 要在 ZooKeeper 上注册自己参与 Master 选举。这里如果连不上 ZK进程会一直重试表现为卡住。成为 Active Master多个 Master 时通过 ZK 选主只有一个能成为 Active其余是 Backup。初始化集群状态这是最关键的一步。Active Master 要确认hbase:meta表的位置、检查 RegionServer 的注册情况、处理上电时的 region 分配assignment。进入运行态完成上述步骤后Master 才把内部状态标记为可用开始响应客户端。PleaseHoldException就是在第 4 步没走完时抛出来的。客户端HBase Shell通过 RPC 调用 Master 的createTable方法Master 一看自己还没到运行态直接回一个PleaseHoldException意思是稍后再试。2.2 为什么这个异常名字会误导人问题在于第 4 步初始化集群状态可能因为各种原因长时间卡住甚至永远卡住而不是几秒钟就过去。这时候异常信息还是那句Master is initializing但实际原因可能是hbase:meta表所在的 RegionServer 没起来Master 找不到 metaZooKeeper 里残留了上一次集群的脏数据Master 在等一个永远不会来的节点hbase.rootdir指向的 HDFS 路径权限不对Master 读写 meta 失败RegionServer 因为时钟不同步、端口冲突等原因反复掉线Master 一直在等它们稳定。所以Master is initializing翻译成人话应该是Master 还没进入可服务状态具体卡在哪你得去看日志。光看 Shell 的报错信息量几乎为零。2.3 一个容易被忽略的细节meta 表的特殊性在 HBase 2.x 之前hbase:meta的位置信息存在 ZooKeeper 的/hbase/meta-region-server节点里。Master 启动时要读这个节点找到 meta 所在的 RegionServer然后才能继续。如果这个节点指向了一个已经不存在或者没起来的 RegionServerMaster 就会一直等表现为初始化卡死。HBase 2.x 之后meta 表的管理方式有所调整但核心逻辑没变Master 必须能定位并访问 meta 表才能完成初始化。这也是为什么很多初始化卡住的问题根子都在 meta 或 RegionServer 上而不是 Master 本身。理解了这一层你就明白为什么下面这些排查方向是有效的——它们都是在检查Master 完成初始化所依赖的前置条件是否满足。3. 按图索骥一套可复现的排查链路遇到这个报错最忌讳的就是上来就stop-hbase.sh然后重启。重启能解决一部分偶发问题但如果是配置或环境问题重启一百次也没用还会把现场破坏掉。正确的做法是先保留现场按顺序排查。下面这套链路是我自己反复用过、也帮别人定位过问题的顺序从最外层往里查。3.1 第一步确认 Master 进程和日志的真实状态先别急着看 Shell登到 Master 所在机器上确认进程和日志。# 查看 HBase 相关进程 jps | grep -E HMaster|HRegionServer|HQuorumPeer # 查看 Master 日志路径因版本和配置而异常见如下 tail -f $HBASE_HOME/logs/hbase-*-master-*.log重点看日志里有没有这几类关键字Master is initializing或PleaseHoldException确认异常确实来自 Master 内部。Waiting for RegionServers to check-inMaster 在等 RegionServer 注册。Assigning regions/meta正在处理 meta 或 region 分配。Connection refused/No route to host网络或端口问题。KeeperErrorCode/Session expiredZooKeeper 连接问题。如果日志停在某一行不动了那一行往往就是卡点。比如日志反复打印Waiting for RegionServers to check-in说明 Master 在等 RegionServer问题在 RegionServer 侧不在 Master。提示排查期间不要清空日志也不要急着重启。日志里卡住前的最后几行是定位问题的黄金信息。3.2 第二步检查 ZooKeeper 的状态和残留节点ZooKeeper 是 HBase 的通讯录Master 和 RegionServer 都靠它协调。ZK 出问题Master 初始化必然受影响。# 连接 ZK假设 ZK 在本地 2181 端口 $HBASE_HOME/bin/hbase zkcli # 在 zkcli 里查看 HBase 相关节点 ls /hbase ls /hbase/meta-region-server get /hbase/meta-region-server常见的坑/hbase/meta-region-server节点存在但指向的 RegionServer 已经挂了或换了地址。Master 读到这个过期地址去连却连不上就一直等。/hbase/rs下残留了大量已经下线的 RegionServer 节点临时节点本应随会话消失但如果 ZK 会话超时设置不当或进程被 kill -9可能残留。ZK 里还有上一次集群的/hbase数据而 HDFS 上的hbase.rootdir已经被清空或换了路径两边对不上。处理这类问题的原则是要么让 ZK 和 HDFS 的状态一致要么彻底清空重来。如果这是一个可以重建的测试集群最干净的做法是停掉所有 HBase 进程清空 ZK 的/hbase节点清空 HDFS 的hbase.rootdir然后重新启动。但如果是生产环境清空意味着数据丢失必须谨慎优先尝试修复指向关系。3.3 第三步确认 RegionServer 是否正常注册Master 初始化需要 RegionServer 上线并注册。如果 RegionServer 一个都没起来或者起来了但注册失败Master 就会一直等。# 在 RegionServer 机器上查看进程 jps | grep HRegionServer # 查看 RegionServer 日志 tail -f $HBASE_HOME/logs/hbase-*-regionserver-*.logRegionServer 起不来的常见原因时钟不同步HBase 对集群内机器的时间差敏感差太多会导致 RegionServer 被 Master 拒绝。用ntpdate或时间同步服务对齐。端口冲突RegionServer 默认端口 160202.x或 600201.x被占用就起不来。HDFS 权限问题RegionServer 需要读写hbase.rootdir如果 HDFS 上该目录属主不对会报权限拒绝。hosts 解析问题机器名解析不到或解析成 127.0.0.1导致注册的地址 Master 连不上。在 Master 日志里如果看到Received REGION_SERVER_REGISTRATION之类的记录说明注册在走如果一直没看到问题就在 RegionServer 侧。3.4 第四步核对 hbase.rootdir 与 HDFS 状态Master 初始化时要读写hbase.rootdir通常是 HDFS 上的/hbase。这个路径如果不对Master 直接卡死。# 查看配置的 rootdir grep -A1 hbase.rootdir $HBASE_HOME/conf/hbase-site.xml # 检查 HDFS 上该路径 hdfs dfs -ls /hbase hdfs dfs -ls /hbase/data要确认的点路径存在且 Master 进程的用户有读写权限。/hbase/data/hbase/meta目录存在这是 meta 表的数据。如果这个目录被误删Master 找不到 meta初始化就会失败。HDFS 处于正常状态没有进入安全模式。hdfs dfsadmin -safemode get查看如果是 ON需要先退出安全模式。我遇到过一次是因为 HDFS 集群重启后进入了安全模式HBase Master 一直连不上 HDFS日志里刷了一堆重试Shell 那边就报PleaseHoldException。退出安全模式后Master 几秒钟就完成初始化了。3.5 第五步用 Web UI 和 Shell 交叉验证HBase Master 默认有个 Web UI端口 160102.x或 600101.x。打开http://master-host:16010能看到 Master 的状态、RegionServer 列表、表列表。如果页面能打开但显示 Master is initializing 或 RegionServer 列表为空印证了前面的判断。如果页面都打不开说明 Master 的 Web 服务都没起来问题更靠前进程或端口层面。Shell 里也可以用status命令看集群状态hbase(main):001:0 status正常会返回类似1 active master, 2 backup masters, 3 servers, ...。如果返回异常或卡住结合日志一起看。4. 几类高频根因的深度拆解与处理上面是通用排查链路下面把最常见的几类根因单独拎出来讲透每一类都给出为什么和怎么办。4.1 根因一ZooKeeper 脏数据导致 Master 等一个不存在的节点这是新手最容易踩、也最容易被误判为再等等就好的坑。场景通常是你之前搭过一次集群没清干净就重搭或者改了机器名、换了 IP。现象Master 日志里反复出现连接某个地址失败或者卡在读/hbase/meta-region-server。Shell 报PleaseHoldException等多久都没用。原因ZK 里保存的是上一次集群的元数据指向的 RegionServer 地址已经不存在。Master 启动时读到这个地址尝试连接超时后重试循环往复永远走不到下一步。处理# 停掉所有 HBase 进程 stop-hbase.sh # 连接 ZK删除 /hbase 节点谨慎确认是可重建的集群 $HBASE_HOME/bin/hbase zkcli rmr /hbase # 如果 HDFS 上的数据也要清测试环境 hdfs dfs -rm -r /hbase # 重新启动 start-hbase.sh注意rmr /hbase会删掉整个 HBase 在 ZK 上的元数据生产环境执行前必须确认数据可丢或有备份。生产环境更稳妥的做法是修复/hbase/meta-region-server的指向而不是一删了之。4.2 根因二RegionServer 未注册或反复掉线现象Master 日志停在Waiting for RegionServers to check-in或者 RegionServer 列表一会儿有一会儿没。原因RegionServer 进程没起来、起来了但注册失败、或者注册后因为心跳超时被 Master 踢掉。常见诱因是时钟不同步、内存不足导致 GC 停顿过长、网络抖动。处理先确认 RegionServer 进程在不在不在就看它的日志为什么退出。检查集群各机器时间date对比差值超过默认阈值hbase.master.maxclockskew默认 30 秒就会出问题。检查 RegionServer 的堆内存hbase-env.sh里的HBASE_HEAPSIZE是否够用。内存太小会导致频繁 Full GC心跳发不出去。看 Master 日志里有没有RegionServer ... expired之类的记录有的话就是心跳超时。4.3 根因三HDFS 权限或安全模式问题现象Master 日志里大量 HDFS 相关异常如Permission denied、SafeModeException。原因hbase.rootdir目录属主不是启动 HBase 的用户或者 HDFS 处于安全模式。处理# 检查安全模式 hdfs dfsadmin -safemode get # 如果是 ON退出 hdfs dfsadmin -safemode leave # 修正目录属主假设 HBase 用 hbase 用户启动 hdfs dfs -chown -R hbase:hbase /hbase hdfs dfs -chmod -R 755 /hbase4.4 根因四配置文件不一致或关键参数错误现象集群各节点行为不一致Master 和 RegionServer 对不上。原因hbase-site.xml在各节点上不一致或者hbase.zookeeper.quorum、hbase.rootdir等关键参数写错。处理用scp或配置管理工具保证所有节点的conf目录一致。重点核对参数作用常见错误hbase.rootdirHBase 数据在 HDFS 的根路径写成 localhost 或路径不存在hbase.zookeeper.quorumZK 集群地址漏写节点或写错端口hbase.cluster.distributed是否分布式模式伪分布式下写成 false 导致用本地文件系统hbase.master.maxclockskew允许的最大时钟偏差默认 30 秒跨时区机器容易超5. 那些年我踩过的坑几个真实教训排查链路讲完了但真正让人长记性的往往是踩坑的过程。下面这几个是我自己或身边人真实遇到过的写出来给你避雷。5.1 坑一以为等一会儿能解决结果等了一下午第一次遇到这个报错时我的反应和大多数人一样Master 在初始化那就等。结果从下午等到下班Shell 还是那句PleaseHoldException。后来才发现是 ZK 里残留了旧集群的 meta 节点Master 一直在等一个不存在的 RegionServer。教训这个报错如果超过正常启动时间一般 1-2 分钟还没消失就一定是卡住了别再等去看日志。5.2 坑二反复重启把现场破坏了有一次集群出问题我习惯性地stop-hbase.sh然后start-hbase.sh重启了三四次。每次重启后日志都被覆盖等我终于想起来看日志时最早的错误信息已经找不到了。教训出问题先看日志、先保留现场重启是最后手段。如果非要重启先把当前日志备份出来。5.3 坑三时钟不同步这个隐形杀手有次在一批新机器上部署Master 起来了RegionServer 也起来了但就是注册不上。查了半天配置和网络都没问题最后date一对比发现其中一台机器时间慢了 5 分钟。HBase 默认允许的最大时钟偏差是 30 秒超了就直接拒绝。教训部署 HBase 前先把所有机器的时间同步做好这是基本功。5.4 坑四HDFS 安全模式被忽略HDFS 集群重启后有时会自动进入安全模式这时候 HBase 读写 HDFS 会失败。我一开始只盯着 HBase 日志看没往 HDFS 想绕了很大一圈。教训HBase 的问题很多时候根子在它依赖的组件上HDFS、ZK排查时要往外看一层。6. 防患于未然让这个报错少出现的几条经验与其每次出问题再排查不如在部署和日常维护时就把一些事情做对。下面这几条是我总结下来最能减少这类问题的习惯。6.1 部署前的检查清单在第一次启动集群前按这个清单过一遍能挡掉大部分低级问题所有机器时间同步偏差在 30 秒内。/etc/hosts或 DNS 能正确解析所有节点的主机名且不解析成 127.0.0.1。hbase-site.xml在所有节点一致关键参数核对无误。HDFS 上hbase.rootdir目录存在属主和权限正确。ZooKeeper 集群正常/hbase节点是干净的新集群。各节点防火墙放行 HBase 和 ZK 所需端口。6.2 日常维护中值得养成的习惯改配置后全量同步任何hbase-site.xml的改动都要同步到所有节点别只改一台。重启有顺序一般先停 HBase再停 ZK再停 HDFS启动反过来。乱序重启容易产生状态不一致。监控 Master 和 RegionServer 的心跳很多问题在爆发前都有征兆比如 RegionServer 频繁掉线。保留日志日志轮转策略别设得太激进出问题时能翻到历史记录。6.3 一个实用的快速自检脚本思路你可以写一个简单的脚本在报错时一键收集关键信息省得手忙脚乱#!/bin/bash echo 进程状态 jps | grep -E HMaster|HRegionServer|HQuorumPeer echo Master 日志尾部 tail -n 50 $HBASE_HOME/logs/hbase-*-master-*.log echo ZK /hbase 节点 echo ls /hbase | $HBASE_HOME/bin/hbase zkcli 2/dev/null echo HDFS rootdir hdfs dfs -ls /hbase 2/dev/null echo HDFS 安全模式 hdfs dfsadmin -safemode get这个脚本不解决任何问题但能在几秒内把排查需要的信息摆到你面前比一条条敲命令快得多。我自己就常备这么一个出问题时先跑一遍心里就有底了。说到底PleaseHoldException: Master is initializing这个报错本身不可怕可怕的是被它的字面意思带偏以为等等就好。它更像是一个总闸没合上的信号真正的原因藏在 Master 依赖的 ZooKeeper、HDFS、RegionServer 这些环节里。把排查链路走一遍把日志看仔细绝大多数情况都能定位到具体原因。我个人在实际操作中的体会是遇到 HBase 的报错永远先怀疑它依赖的组件再怀疑它自己这个思路帮我省下了大量瞎折腾的时间。
阅读完成 · 觉得有帮助?
咨询建站