尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

HBase HMaster 端口消失排查思路与根因详解

HBase HMaster 端口消失排查思路与根因详解 凌晨三点被监控电话叫醒屏幕上的告警写着HMaster端口消失。说实话干了大数据运维的人看到这类告警第一反应通常不是端口被谁占了而是HMaster进程是不是又没了。端口只是一个表象真正的问题往往藏在进程、日志、ZooKeeper会话和GC停顿里。这篇文章想把我排查HBase HMaster端口消失问题的方法论完整梳理一遍从确认现象、区分进程与端口到日志定位、根因修复和预防手段尽量讲清楚每一步为什么这么做。如果你是刚接手HBase集群的运维、SRE或者被这类问题折腾过但没理清头绪这篇应该能帮你省不少时间。1. 端口消失的三张脸先分清问题到底长什么样很多人听到HMaster端口消失第一反应是跑过去netstat -anp | grep 16010结果没输出然后就开始怀疑是不是防火墙、安全组、端口扫描的误报。我踩过这个坑所以特别想强调端口消失只是一个结果你要先搞清楚是以下三种情况里的哪一种排查方向完全不同。1.1 HMaster的端口清单RPC端口和Web UI端口别和老版本搞混HMaster对外暴露的端口主要有两个都定义在hbase-site.xml里hbase.master.port默认是16000这是HMaster的RPC端口HBase客户端、RegionServer通过这个端口跟HMaster通信处理DDL、meta操作、Region分配等请求。hbase.master.info.port默认是16010这是HMaster的Web UI端口浏览器访问集群状态、Region分布、Table列表都走它。这里有个特别容易踩的坑很多老资料里写的是60000和60010那是HBase 0.98之前的老端口升级到0.98以后就改成了16000和16010。如果你拿老文档去对第一眼就会误判端口不是标配。另外别把RegionServer的16020RPC和16030Web UI也混进来它们和HMaster端口是两套东西告警和排查时要分开看。清楚了这两个端口分别负责什么你才能判断故障面如果只是16010打不开但业务读写正常问题可能只是Web服务如果16000也连不上那基本可以断定HMaster服务本身出了问题。1.2 三种消失表现分别意味着什么根据我在线上看到的实际情况端口消失通常表现为三种形态进程完全没了端口自然消失。jps看不到HMasterss -lntp | grep 16010没有任何输出。这是最常见的原因是HMaster进程崩溃退出比如ZooKeeper会话超时后主动abort。这种情况排查重点在日志。进程还在但端口不在监听。少见但存在。可能是hbase.master.port或hbase.master.info.port被改成了别的值进程启动成功但也绑到了新端口上监控还按老端口去探测于是报端口消失。这种问题本质上是配置漂移或监控项没跟着配置走。端口偶尔出现、然后又消失。这通常意味着HMaster在反复重启。你可能隔几分钟能看到一次16010甚至赶上能打开一下Web UI然后马上就断了。这种情况最阴间因为很多人会误以为是网络抖动实际上是进程启动后很快崩溃被脚本或看门狗拉起再崩溃循环往复。想明白自己是哪一种再去执行下面的排查步骤这样才不会一上来就钻到防火墙和端口占用的牛角尖里。2. 从进程开始jps、ss和/proc一个都不能少确认现象之后我的习惯是先登录HMaster所在节点按顺序做三件事看进程、看端口、看/proc。这样才能把端口消失拆解成可继续往下追的事实。2.1 先用进程状态区分进程没了和进程活着但没监听第一件事是跑jps。注意要用HBase服务的系统用户跑或者用sudo -u hbase jps否则经常看不到Java进程又平白多一层怀疑。sudo -u hbase jps 53429 HMaster 53436 HRegionMaster # 这行一般不存在只是举例说明输出长什么样如果jps能看到HMaster继续用ss确认监听状态ss -lntp | grep -E 16000|16010这里有输出说明进程活着、端口也在监听那监控报端口消失就要去查监控探测点的网络路径和监控配置。如果没有输出那就要看进程是不是处于僵死状态用ps -o pid,ppid,stat,etime,cmd -p PID看STAT是不是D不可中断睡眠或者Z僵尸。Java进程僵死的概率很低但一旦发现STAT异常基本可以判断这一台节点的操作系统环境有问题比如负载异常、磁盘IO卡死。如果jps根本找不到HMaster那就干净利落进程死了去看日志。这也是为什么我一直强调先确认进程状态因为端口消失和进程死亡是两个层面的问题处理手段完全不同。2.2 绑定地址的坑为什么ss看到的是0.0.0.0或具体IP另一个容易被忽略的细节是绑定地址。HBase里hbase.master.hostname、hbase.master.bindAddress等配置会影响进程实际绑定的IP。有些部署会在hbase-site.xml里显式把hbase.master.info.bindAddress指定为内网IP这时候ss -lntp | grep 16010看到的就不是0.0.0.0:16010而是172.xx.xx.xx:16010。有次排查一个端口消失告警现场在服务器上明明能看到监听但监控就是不通过最后发现是监控探针探测的是0.0.0.0或者走了一个网络策略不通的IP段。这个坑排查起来非常烦人所以我一般在排查流程里会建议直接看ss -lntp输出的完整监听地址并用lsof -i :16010交叉验证。如果监听地址正常但从外部探不到再往网络策略、安全组方向走那就靠谱多了。如果进程和端口都对得上我还会顺手看下/proc/PID/cmdline确认它启动参数里加载的hbase-site.xml路径是不是预期的那份。尤其像是多套集群共用一套安装目录或者有人改了环境变量HBASE_CONF_DIR的情况进程启动用的配置和你以为的配置可能不是同一个文件端口自然对不上。3. 顺着日志找真凶HMaster崩溃的常见根因画像确认HMaster进程确实死亡后接下来唯一正确的事就是看日志。HMaster的日志一般在$HBASE_HOME/logs/下文件名类似hbase-hbase-master-hostname.log。如果是托管发行版CDH、HDP这类日志路径可能被打到了别的地方用发行版自己的日志入口看也一样。我自己总结过HMaster进程死亡、端口消失最常见的几类根因下面逐一说清楚。3.1 ZK会话超时最经典的自杀式退出HMaster启动后会向ZooKeeper注册一个临时节点用来持有Active Master锁。一旦HMaster跟ZooKeeper之间的会话心跳超时默认zookeeper.session.timeout是180秒部分发行版会改成60秒ZooKeeper就会删除这个临时节点HMaster发现自己已经丢锁会主动执行abort整个进程退出。日志里会看到类似这样的一段INFO org.apache.zookeeper.ClientCnxn: Client session timed out, have not heard from server in 180000ms INFO org.apache.hadoop.hbase.master.HMaster: Aborting... our ZooKeeper session was lost这类问题多发于几种场景HMaster所在节点GC停顿太久、ZooKeeper集群本身抖动、HMaster和ZK之间网络延迟异常。要找真正的元凶还得再往下挖比如GC日志、ZK服务端日志、网络延迟监控。3.2 NameNode SafeModeHMaster反复重启的元凶第二种常见的场景是HDFS进入SafeMode。HMaster启动时需要往HDFS上读写系统表meta表、namespace表等如果NameNode处于SafeMode这些写入会失败HMaster启动流程就会不断重试最终abort。这种场景的日志里你会看到大量的RetriesExhausted、SafeModeException之类的报错同时伴随便用者反馈整个集群的DDL操作全部失败。排查时去NameNode上跑hdfs dfsadmin -safemode get确认状态再做相应的退出SafeMode或修复HDFS的处置。这个坑坑在很多人只看HBase日志怎么都找不到原因其实问题在上游HDFS。3.3 双HMaster主备抢锁看似活着其实一直在轮换如果集群配了多个HMaster一主一备或一主多备有时你会看到两个HMaster进程都在但Active Master的端口隔一会儿就消失一次。这通常不是端口问题而是主备在反复抢锁。常见原因是hbase.master.lease.period或其他与ZK会话、锁超时相关的参数在两台Master上配置不一致或者两个节点的时钟不同步NTP没配好导致ZooKeeper的锁被异常抢占。排查这类问题最直接的办法是看ZooKeeper上谁持有Active锁zkCli.sh -server zk1:2181 ls /hbase/master get /hbase/master正常情况/hbase/master这个临时节点只有一个持有者反复变化就说明主备在抢。同时建议在两台HMaster的日志里搜索negotiating master、becoming active master这类关键词基本就能看到抢锁的时间线。3.4 端口被占与bind失败启动即死的隐藏坑还有一种不常见但一碰就死的情况端口被别的进程占了。HMaster启动时如果hbase.master.port16000已经被其他进程占用会抛出java.net.BindException: Address already in use进程直接退出看起来就是端口消失——准确说是一直没出现。这种情况多发生在同机部署了多个Java服务、有人手动起了一个测试进程占用了端口、或者旧HMaster进程没死干净比如进程变成了僵尸或者还在TIME_WAIT阶段的时候。处理方式也不复杂用lsof -i :16000看是谁占用确认是不是残留的旧HMaster进程该kill就kill清理干净后重新拉起HMaster。不过要提醒一句如果端口是刚被杀掉的进程留下的偶尔能看到Address already in use是因为端口还处于TIME_WAIT这时候一般等30秒到2分钟就能恢复不建议强制去改系统参数。真正要警惕的是端口被完全不相干的服务占用那就要查是不是端口规划冲突了。4. 一次完整排查从端口没了到GC停顿导致会话超时光讲根因画像有点抽象我拿最近一次踩坑的完整过程做个示例把上面这些判断串起来。当时环境是HBase 2.3.x两个HMaster节点8个RegionServer凌晨3点17分监控报警hbase_master_web_port(16010) down5分钟后自动恢复但2小时后再次down用户侧反馈写入超时变多。4.1 收拢现场监控截图、jps结果与日志路径我先做了三件事第一保留监控面板的截图把down和recovery的时间点记录下来第二登录master1看进程状态发现jps已经找不到HMaster第三确认另一台备节点master2上HMaster还在但同样是备状态。这里有个观察很关键按说双HMaster部署时Active Master挂了另一个应该马上接管端口不至于消失太久。但实际情况是master2接管后自己也因为同样的原因在陆续重启两个节点都在反复横跳所以从监控视角看端口就是偶尔出来一下又消失。4.2 对齐时间线日志在凌晨3点17分前后说了什么接下来我把master1和master2的HMaster日志拉出来按时间对齐看。master1在3点17分前有一段比较密集的日志先是RegionServer汇报Region长时间处于RITRegion In Transition然后是HMaster与ZooKeeper之间出现大量重连最后出现了一句决定性的日志INFO org.apache.zookeeper.ClientCnxn: Client session timed out, have not heard from server in 180000ms INFO org.apache.hadoop.hbase.master.HMaster: Aborting... our ZooKeeper session was lost这说明HMaster是在ZK会话超时后主动abort的。但问题还没完——为什么会话会超时HMaster和ZooKeeper之间的心跳正常每10秒左右一次除非进程卡死否则很难连续180秒没心跳。我继续翻进程退出前的系统日志和GC日志。4.3 验证GC停顿从GC日志拿到实锤在HMaster的GC日志里我找到了关键证据3点15分到3点17分之间Master节点的堆内存连续发生了3次Full GC每次停顿时间在30秒以上最严重的一次接近60秒。GC是在把堆挤爆之后触发的连锁反应而这期间进程根本没有机会给ZooKeeper发心跳。换句话说不是网络问题不是ZooKeeper问题是HMaster被GC冻住了。顺着GC停顿继续查发现HMaster堆内存配置只有4GB但几千个Region的meta信息和大量请求堆积导致堆使用率长期在90%以上。Full GC频繁触发停顿时间一长ZK会话超时就成了必然结果。这里也可以解释为什么两个HMaster节点轮着重启两个节点配置完全一样都在高负载下GC谁当Active谁先扛不住然后备机接管后又轮到自己GC超时形成恶性循环。5. 修复与预防参数调整、自动拉起与巡检脚本找到根因后修复分成了两步走先把眼前的问题压下去再把长期存在的隐患排掉。下面这些调整和脚本都是我实际用过的可以作为参考。5.1 针对性修复session超时与HMaster堆内存怎么调才稳针对这次GC停顿导致ZK会话超时的问题我做了三件事第一把hbase-site.xml里的zookeeper.session.timeout从默认的180000ms调大到300000ms。这里不是鼓励无脑调大而是在确认GC停顿峰值不超过60秒、且调大后不影响故障接管速度的前提下做的缓冲。如果直接把超时调大到10分钟主备切换会变得非常迟钝反而引入新风险。第二把HMaster堆内存从4GB调整到8GB并显式配置GC参数。我用的是G1property namehbase.env.opts/name value-Xms8g -Xmx8g -XX:UseG1GC -XX:MaxGCPauseMillis200/value /property同时把HMaster启动脚本里的HBASE_OPTS调整好避免让RegionServer把Master需要的参数给覆盖了。调整后观察了两周Full GC频率从原来每小时好几次降到了一天一两次GC停顿最长的也就一两秒。第三配置了进程异常退出自动拉起。用systemd管理HMaster进程是最省心的方式崩溃后自动拉起配合日志采集能很快恢复服务。systemd单元文件里要设置Restarton-failure、RestartSec15s同时注意启动顺序依赖确保ZooKeeper和HDFS就绪后再拉起HMaster。[Unit] DescriptionHBase Master Afternetwork.target zookeeper.service hdfs-namenode.service [Service] Typeforking Userhbase EnvironmentFile/etc/sysconfig/hbase ExecStart/opt/hbase/bin/hbase-daemon.sh start master ExecStop/opt/hbase/bin/hbase-daemon.sh stop master Restarton-failure RestartSec15s LimitNOFILE65536 [Install] WantedBymulti-user.target5.2 巡检脚本与监控指标别只盯着一个端口值经历了这次告警之后我把监控项从端口是否存在升级成了端口 进程 锁 GC 会话的多维度检查。只盯端口值有个问题HMaster进程还活着、端口也占着但Master可能已经在abort流程里或者已经失去ZK锁却不自知端口却还挂在那边。所以我现在会用一个组合脚本做巡检核心逻辑是先查进程再查端口最后查ZooKeeper上的Active状态。#!/bin/bash LOG/var/log/hbase_master_health.log PID$(pgrep -f HMaster | head -1) if [ -z $PID ]; then echo $(date %F %T) HMaster process not found $LOG exit 1 fi PORT$(ss -lntp | grep 16010 | grep -c pid$PID) if [ $PORT -eq 0 ]; then echo $(date %F %T) HMaster port 16010 missing but process alive, check bind/config $LOG exit 2 fi zkClient/path/to/zkCli.sh -server zk1:2181 ACTIVE$($zkClient get /hbase/master 2/dev/null | grep -E ^8080|^16000 | head -1) if echo $ACTIVE | grep -qv $PID; then echo $(date %F %T) process $PID not holding active master lock $LOG fi脚本里判断锁哪一行只是示例生产上我更建议用监控JMX指标里的HbaseMaster.isActiveMaster来直接拿到Active状态。像这种能被JMX直接暴露的指标就别靠shell去解析ZooKeeper输出稳定性差很多。监控指标方面除了端口存活我重点盯这几个HbaseMaster.isActiveMaster判断当前Master是否持有Active锁比单纯看端口可靠得多。MasterHeapUsed和GC暂停时间这两项能提前预警GC停顿引发的会话超时。ZooKeeper连接数和服务端平均延迟HMaster的ZK会话超时很多时候是ZK集群先出问题的不能只看HBase侧。RegionServer到HMaster的RPC调用失败次数这个指标上升往往比端口消失告警更早。5.3 一点运维心得最后分享一点个人体会。HMaster端口消失这类问题表面上是端口监控告警本质上是在提醒你这套集群的某个环节已经处于不健康状态。端口只是服务的外在表现真正的病灶可能在JVM堆、GC参数、ZK会话配置、HDFS状态甚至只是主机时间不同步。我每次排查时会强迫自己按进程状态 → 端口监听 → 端口对应角色 → 日志时间线 → 依赖服务状态的顺序走不要看到端口消失就直接去查防火墙和端口占用那样很容易白忙一场告警还在那边闪现场还没找到。如果你在实际排查中遇到了和我这里描述的某个特征相似的场景比如日志里出现了ZooKeeper session expired或者HMaster日志里反复出现SafeModeException那就优先往对应方向深挖。端口不会凭空消失每次消失背后都有一行写到一半的日志在等你翻开它。
返回列表