HBase RegionServer进程消失全解析:从日志到根因定位

HBase RegionServer进程消失全解析:从日志到根因定位
凌晨三点监控大屏上的RegionServer存活数量突然少了一台。登录到对应节点jps一看——HRegionServer进程没了。没有人执行过kill没有做升级变更没有重启操作日志里也看不到干净的SHUTDOWN记录。一个运行中的HBase 2.4.12 RegionServer就这么“自主消失”了。这种问题很邪门但一点也不罕见。HBase的RegionServer进程“平白无故消失”在排障群里几乎是月月见。尤其是2.4.x这个分支升级到2.4.12之后还会遇到一些老版本不常见的坑。很多同学第一反应是“是不是被人误杀了”“是不是定时任务清理了进程”——查了一圈发现都没有最后在日志和系统消息里才找到真相。这篇文章我就以2.4.12版本的线上排障为例把“RegionServer自主消失”这件事彻底拆开。先说清楚它会以哪几种形态“消失”再逐个分析背后的典型原因然后带你把一次完整的排查流程走一遍最后给出一份可以直接抄作业的速查表和参数配置建议。无论你是刚接触HBase的新手还是被线上故障折磨过的老手这篇文章应该都能帮你省下不少时间。1. 先搞清楚“自主消失”到底是怎么个消失法1.1 进程级消失和节点级消失不是一回事很多人一看到“RegionServer消失了”第一反应就是“进程死了”。但在做任何排查之前你最先要确认的是它到底属于哪一种“消失”。第一种是进程真的没了。ps -ef | grep HRegionServer查不到jps也看不到/proc/{pid}目录不存在。这种说明JVM确实退出了。它可能是自己调用了System.exit()可能是被OOM Killer杀了也可能是出现了致命的OutOfMemoryError导致JVM崩溃。第二种是进程还在但服务已经不可用。你会发现ps还能看到Java进程CPU占用也很低但Web UI上这个RegionServer已经显示为DEADHBase Master日志里出现了regionserver expired之类的字样。这种情况本质上是RegionServer和ZooKeeper之间的会话断了Master判定它已经失联会把它从存活的RegionServer列表里摘掉。在业务侧看起来就像“它消失了”后台重新分配了它上面的region。这时候进程没死只是“社会性死亡”了。第三种是节点层面的假死。比如磁盘满了导致日志写不进去或者网络抖动导致和HDFS的DataNode、其他RegionServer的RPC全部超时。监控上看到的是RegionServer状态异常、接口报错像是进程出了问题但实际上是整个节点的基础设施出了问题。这三种形态的定位方向完全不同。所以遇到“自主消失”第一步永远不是Google“HBase regionserver disappeared”而是先搞清楚它属于哪一类。我见过太多同学在进程明明还活着的情况下花了一个多小时去查GC日志方向从一开始就错了。1.2 2.4.12这个版本为什么值得单独拿出来说HBase 2.4.12属于2.4.x维护分支里的一个后期修订版本。相比2.4.0到2.4.5这些早期版本它修了不少问题尤其是和HDFS 3.x的兼容性、部分Compaction场景下的性能问题、以及一些会在特定条件下引发RegionServer崩溃的bug。但这不意味着2.4.12就“万事大吉”。实际运维中2.4.12反而有两个容易被忽视的特点第一个特点它默认的GC策略是G1。HBase 2.x在很长一段时间里默认使用G1GC但G1在RegionServer这种“大堆高分配速率”的场景下如果参数不调优很容易出现Full GC过长进而触发ZooKeeper会话超时。这个问题在2.4.x上特别典型因为它的默认堆内存相关的参数在某些机器配置下会被自动算得偏大。第二个特点2.4.x引入了更多堆外内存的使用场景。比如Netty、比如某些写路径上的ByteBuffer。如果-XX:MaxDirectMemorySize没设置或者设置得太小就可能出现Direct buffer memory引发的OOM而这类OOM在常规JVM堆内存监控里根本看不出来。所以2.4.12的“自主消失”既有共性原因也有版本特性。下面这些原因分析里我会特意标注哪些问题在2.4.12上更容易出现。2. RegionServer 会“自杀”的几种典型原因2.1 堆内存溢出和堆外内存泄漏隐藏最深的“进程终结者”最常见也最容易被找到的是Java堆内存溢出。RegionServer的堆里主要装两样东西MemStore内存中的写缓存负责暂存还没刷盘的写入数据和BlockCache读缓存缓存HFile的Block。如果写入量突然暴增MemStore占用超过阈值同时又触发不了正常的flush刷盘堆内存就会被撑爆。在日志里你会看到类似这样的记录java.lang.OutOfMemoryError: Java heap space或者更隐蔽的java.lang.OutOfMemoryError: GC overhead limit exceeded前者说明堆真的不够用后者说明JVM在GC上花费的时间占比太高默认超过98%却没回收出多少空间——基本上等于“堆内存接近耗尽、GC已经聊胜于无”的死亡前奏。真正难排查的是堆外内存泄漏。我在2.4.12上遇到过不止一次堆内存的监控曲线很好看GC也很正常但RegionServer每隔一两周就“消失”一次。查系统日志发现是OOM Killer把进程杀了但堆内存明明很宽裕。这种问题的根源往往是堆外内存Direct Memory持续增长。HBase在读写路径上会使用堆外ByteBuffer来减少GC压力但如果在某些异常情况下比如客户端连接大量断开、Compaction反复失败这些Direct Buffer没有被及时释放就会一直累积。当累计值超过-XX:MaxDirectMemorySize如果没显式设置默认等于堆大小时就会抛出java.lang.OutOfMemoryError: Direct buffer memory还有一种更麻烦的情况是JVM本身没有报OOM而是堆外内存涨到了操作系统级别的限制。比如JVM堆设置了8G堆外却悄悄占用了十几个G整个物理机内存被打满触发了Linux的OOM Killer。这种就不是HBase日志能直接看到的了必须去看系统日志。2.2 GC停顿把 ZooKeeper 会话拖死了HBase的RegionServer和ZooKeeper之间维持着一个临时节点/hbase/rs/{hostname},{port}。RegionServer通过定期发送心跳来续约这个机制的底层是ZooKeeper的会话保活。如果RegionServer在会话超时时间内没有向ZooKeeper发送任何心跳ZooKeeper就会判定会话过期把这个临时节点删掉。对于RegionServer默认的ZooKeeper会话超时时间是90秒zookeeper.session.timeout90000。90秒看起来很长但对一个正在做Full GC的JVM来说完全可能超过。G1GC在正常情况下会尽量控制停顿但遇到老年代满了、需要Full GC进行大范围压缩时停顿几秒到几十秒都很正常。如果停顿超过了ZooKeeper会话超时时间后果就是RegionServer和ZooKeeper的会话过期。ZooKeeper删除RegionServer的临时节点。Master发现RegionServer失联标记为DEAD并把它的region分配给其他节点。RegionServer自己的ZK事件处理线程发现会话过期进程触发ABORTING region server直接退出JVM。在HBase 2.4.x里默认GC日志里会记录每次GC的停顿时间。排查这类问题时第一件事就是打开GC日志看看RegionServer消失前后是否有一次超长停顿尤其是“Full GC (Allocation Failure)”或者“Full GC (Ergonomics)”这种。这个原因在2.4.12上很典型因为G1GC面对的往往是几十GB的大堆一旦堆里出现大对象分配或者RSetRemembered Set过大停顿时间会超出预期。更麻烦的是HBase在RegionServer启动时会自动根据机器内存算出一组堆参数如果机器内存特别大比如256G自动算出的堆可能高达几十个GGC压力也会随之变大。2.3 系统 OOM Killer进程“消失”的最大嫌疑犯如果一个Java进程是在没有留下任何OOM异常、没有ABORT日志的情况下突然消失的那就要高度怀疑Linux的OOM Killer。Linux内核在物理内存严重不足时会启用OOM Killer机制选一个“罪恶值”最高的进程直接杀掉。Java进程如果占用了大量物理内存尤其是JVM堆堆外内存线程栈元空间加在一起占了机器内存的大头被选中的概率非常高。被OOM Killer干掉的一个典型特征是HBase日志里没有异常GC日志里也没有OutOfMemoryError但进程就是没了。查日志时你会发现RegionServer在消失前一刻还在正常处理请求突然就断掉了。为什么会有这种“安静地消失”因为OOM Killer是通过kill -9强杀进程的Java进程根本没机会执行任何清理逻辑不会打印堆栈不会写ABORT日志更不会做优雅关闭。触发OOM Killer的场景也很典型。比如同一台物理机上还跑了其他Java服务比如HDFS的DataNode、YARN的NodeManager总内存超了或者RegionServer的堆外内存泄漏导致物理内存被打满又或者是某个线程发生Stack Overflow但OOM Killer先动手了。排查方式很明确dmesg -T | grep -i kill或者直接查/var/log/messages你会看到类似Out of memory: Kill process 123456 (java) score 999 or sacrifice child看到score和java这两个关键字基本就能确认是被内核杀的。接下来要查的是为什么物理内存会不够用。除了堆外内存泄漏之外还要看一眼是不是JVM的元空间、线程栈、以及mmap缓存占用了太多内存。2.4 磁盘、网络这些容易被忽略的“隐形杀手”有一种“自主消失”特别气人查遍所有日志、调了所有参数问题依旧存在最后发现原因居然在HBase之外。磁盘满了是经典中的经典。RegionServer要写WALWrite-Ahead Log写前日志要写HFile要做Compaction每一步都对磁盘有硬性要求。如果存放WAL的目录所在磁盘满了写入阻塞到一定程度就会触发RegionServer的IO错误处理逻辑。在HBase 2.4.12里WAL写入失败会导致RegionServer abort。日志里会看到ERROR org.apache.hadoop.hbase.regionserver.wal: Could not append. Requesting close of WAL英文提示容易看懂但很多人看到ERROR就只知道“坏了”没意识到根因其实是磁盘空间。网络抖动也会让RegionServer莫名“消失”。RegionServer和ZooKeeper之间、RegionServer和HDFS之间、RegionServer和RegionServer之间都有网络通信。如果节点之间网络延迟突然飙高或者出现丢包可能出现两种情况一是RegionServer和ZooKeeper的会话迟迟收不到心跳反馈最后超时过期二是RegionServer和HDFS的DataNode通信超时导致DFSClient报Connection reset by peer进而影响WAL写入引发abort。这类问题在日志里看着像是HBase自身出了问题但测试网络后会发现HBase是“替罪羊”。所以排查时一定不要只盯着HBase日志看。文件句柄数耗尽也需要提一嘴。RegionServer的region越多、连接数越多占用的文件描述符就越多。如果ulimit -n设置得太小比如默认的1024可能运行一段时间后就报Too many open files。这个异常有时候会出现在WAL写入或读取HFile时同样会触发RegionServer退出。2.4.12在高并发场景下文件句柄消耗特别快这个参数一定要按官方建议设置。3. 一次完整的排查实录从进程消失到定位根因3.1 第一件事确认进程状态和硬件资源下面我拿一个实际案例走一遍完整排查流程。假设集群环境是这样的HBase 2.4.123台Master其中1台Active10台RegionServer底层存储是HDFS 3.3。某天凌晨监控报警rs-05节点上的RegionServer进程消失。我的习惯是接到报警后先做“三查”第一查查进程。登录rs-05节点执行jps -l | grep -i hbase ps -ef | grep HRegionServer | grep -v grep注意jps看不到不代表进程一定没了。有一种情况是jps本身因为权限或环境变量问题无法感知到Java进程所以一定要再用ps确认一次。如果有输出记录PID用ls -l /proc/{pid}/cwd和cat /proc/{pid}/status看进程状态。第二查查系统负载和内存。执行top -b -n 1 | head -30 free -g df -h重点看三样东西物理内存还剩多少、Swap有没有大量使用、磁盘空间还有没有剩余。如果物理内存没剩多少优先怀疑OOM Killer如果/或者HBase数据目录所在分区已经100%优先怀疑磁盘问题。第三查查时间和窗口期。看一眼RegionServer消失的时间点和业务高峰期、定时任务、HBase Compaction队列、HDFS Balancer跑批的时间对不对得上。这一步在后续定位时很关键。做完这三查基本能排除一半的可能性。我这次遇到的case是jps完全查不到HRegionServer进程物理内存还有富余大概剩30多G磁盘正常所以“进程被杀”和“磁盘满”暂时排除重点转向日志分析。3.2 从 HBase 日志和 GC 日志里找线索HBase的日志目录通常在HBase安装目录下的logs/里文件命名规则是hbase-{user}-regionserver-{hostname}.log。打开这个日志后记住一个原则不要从头看直接用时间点定位。我习惯先搜几个关键词grep -n ABORTING hbase-hbase-regionserver-rs-05.log grep -n ERROR hbase-hbase-regionserver-rs-05.log | tail -50 grep -n WARN hbase-hbase-regionserver-rs-05.log | tail -50 grep -n OutOfMemory hbase-hbase-regionserver-rs-05.log grep -n System.exit hbase-hbase-regionserver-rs-05.log在这次案例里grep OutOfMemory没有结果grep System.exit没有结果但grep ERROR里出现了一行ERROR org.apache.hadoop.hbase.regionserver.SharedHBaseClientCache: Unexpected exception ... java.io.IOException: Too many open files看到Too many open files线索就出现了。立刻执行ulimit -n cat /proc/{pid}/limits | grep open files如果显示当前进程的打开文件数限制是1024或者65535而且日志里大量出现这个错误基本可以断定是文件句柄耗尽导致RegionServer出问题。在2.4.12里这个异常有时候会出现得很“突然”因为RegionServer运行一段时间后打开的HFile、WAL文件、网络Socket会累积到很大的数量。但光看这一步还不够。日志里没有OOM没有System.exit那JVM退出前的最后痕迹在哪里去GC日志里翻一下。HBase 2.4.12 的GC日志位置不固定很多人会在hbase-env.sh里手动指定比如export HBASE_OPTS$HBASE_OPTS -Xloggc:${HBASE_LOG_DIR}/gc.log-$(date %Y%m%d%H%M%S) -verbose:gc -XX:PrintGCDetails -XX:PrintGCDateStamps如果没有显式指定很多时候GC日志会打捞到nohup.out或者控制台输出。查GC日志时重点看RegionServer消失前15分钟内的GC情况grep -n Full GC gc.log-* | tail -20如果发现Full GC频繁一次Full GC停顿超过20秒那就要把ZooKeeper会话超时纳入主要怀疑对象。如果GC很健康那就继续往下查。3.3 ZooKeeper 侧和 Master 日志怎么看HBase的RegionServer进程是否被Master判定为DEAD在Master的日志里可以找到明确的记录。登录Active Master节点打开hbase-hbase-master-{hostname}.log搜索RegionServer消失前后时间点的记录grep -n rs-05 hbase-hbase-master-*.log | grep -i dead grep -n expired hbase-hbase-master-*.log如果Master日志里有类似这样的记录INFO org.apache.hadoop.hbase.master.ServerManager: Server rs-05,60020,1699999999999 expired INFO org.apache.hadoop.hbase.master.ServerManager: ServerCrashProcessing for rs-05那说明Master已经处理了rs-05的崩溃恢复把它的region重新分配到了别的RegionServer上。但要注意Master日志不能用来判断进程消失的原因只能用来确认影响范围。再看ZooKeeper侧。登录ZooKeeper节点用ZooKeeper自带的客户端工具检查一下RegionServer临时节点的状态zkCli.sh -server zk-node1:2181 get /hbase/rs/rs-05,60020,1699999999999如果节点已经不存在了说明会话过期事件确实发生过。但这依然只能证明结果不能证明原因——因为会话过期既可能是GC停顿导致也可能是网络问题导致还可能是ZooKeeper本身压力过大导致处理心跳变慢。我一般会把ZooKeeper审计日志也翻出来看一眼确认那个时间点ZooKeeper有没有长时间停顿。如果ZooKeeper节点本身有Full GC或者磁盘写延迟也会“误杀”一批RegionServer。这种场景下你看到的会是好几个RegionServer在相近时间点一起过期而不是单一节点的问题。3.4 结合系统消息和文件句柄做最终定性到这一步依然不能盖棺定论。HBase日志里只是出现了Too many open files但为什么会出现这是我们要往下挖的。文件句柄耗尽的背后通常有两个方向一个是连接数太多另一个是文件描述符泄漏。连接数太多的情况很容易理解。RegionServer的和客户端连接、和HDFS的连接、和其他RegionServer做RPC的连接、访问ZooKeeper的连接都占文件描述符。如果客户端连接池配置不合理比如每个应用Server都开了几百个连接RegionServer很容易把文件描述符打满。文件描述符泄漏比较阴险。RegionServer在读取HFile时通过HFile.Reader打开文件正常情况下用完后要关闭。但在某些异常路径下比如Compaction读取文件时抛异常文件句柄没有被正常释放就会造成泄漏。HBase 2.x里曾经有过类似case虽然2.4.12修复了一部分但不能完全排除。我在这次案例里是用lsof -p {pid}去看进程打开的文件列表的。但注意RegionServer进程已经“消失”了拿不到当时的/proc/{pid}/fd内容就只能靠日志推测。好在日志里除了Too many open files还有一个隐藏信息在报错前RegionServer已经运行了将近20天没有重启过。正常运行期间文件描述符被逐渐耗尽这种情况非常符合“泄漏”的特征。最终的定性是RegionServer进程因为文件句柄耗尽WAL写入失败触发了HBase的自我保护机制主动abort退出。它看起来像“自主消失”其实是机制在起作用。有人会问文件句柄耗尽不是应该发生在运行期吗为什么进程会退出因为HBase把WAL写入失败视为“写路径上的致命错误”——如果WAL都写不进去了已经有数据安全风险再继续运行只会让风险扩大所以直接abort让Master把region分配到健康节点上反而更安全。4. 修复方案与关键参数配置详解4.1 内存与GC参数怎么调才合理先说文件句柄问题。这个最简单也最直接在/etc/security/limits.conf里把HBase运行用户的nofile调大。我的建议是至少设成65535生产环境可以直接设成1048576hbase soft nofile 1048576 hbase hard nofile 1048576别忘了同步修改/etc/sysctl.conf里的fs.file-max不然单进程限制虽然放开了系统级上限还是会卡住fs.file-max 2000000 sysctl -p修改后重启HBase进程。如果不想重启可以通过prlimit临时调整prlimit --pid {pid} --nofile1048576:1048576但这个方法对已经快耗尽句柄的进程只能救急长期还是得靠配置文件。再来说GC参数。HBase 2.4.12在hbase-env.sh里提供了SERVER_GC_OPTS变量推荐在JDK 8 G1GC环境下做这样的配置export SERVER_GC_OPTS-XX:UseG1GC -XX:MaxGCPauseMillis100 -XX:ParallelGCThreads8 -XX:ConcGCThreads4 -XX:InitiatingHeapOccupancyPercent60 -XX:G1ReservePercent20关键点有三个第一个是-XX:MaxGCPauseMillis100它只是目标不是绝对保证。G1会尽量向这个目标靠近但在堆快满的时候依然会做Full GC。第二个是-XX:InitiatingHeapOccupancyPercent60。这个参数控制G1在堆使用率达到60%时开始启动并发标记。如果设置太高比如默认的45%在堆使用率80%、90%的时候才开始标记很容易演变成Full GC如果设置太低并发标记太频繁CPU开销又大。我们线上通常设在55到65之间。第三个是-XX:G1ReservePercent。G1GC会预留一部分堆内存用于“失败时的复制”默认10%。RegionServer内存压力大时可以适当调高到20%。但注意这个参数不能盲目调高调高了能用于分配的内存就少了反而可能更早触发Full GC。对于JDK 11G1GC的行为有所变化-XX:UseG1GC依然是默认的但可以加上-XX:UseStringDeduplication来减少重复字符串的内存消耗这个对HBase这种大量使用字符串做region名、表名的场景很有效。4.2 会话超时、重启策略等HBase参数ZooKeeper会话超时相关的参数是zookeeper.session.timeout。RegionServer默认是90000毫秒。如果你发现GC停顿时间偶尔会超过这个值但又不是经常性超时可以考虑适度调大到120000或180000毫秒给GC留出缓冲。property namezookeeper.session.timeout/name value120000/value /property但我必须强调一句调大会话超时只能“缓”不能“治”。它只是给GC和网络抖动留了更多余地根本问题还是GC停顿本身。如果Full GC稳定超过20秒你应该去调GC参数而不是无限调大超时时间。超时时间调太大会带来一个坏处RegionServer假死期间进程还在但已经无法处理请求客户端请求会一直超时重试业务端的等待时间会变长。还有一个参数值得关注hbase.regionserver.restart.on.zk.expire。在部分HBase版本里如果设为trueRegionServer在ZK会话过期后会尝试自己重启而不是直接退出。但这个参数在不同版本的行为不完全一致而且在生产环境里我一般不建议依赖它。更好的做法是交给HBase的进程守护机制比如systemd或者你用的监控系统来自动拉起。如果使用systemd管理RegionServer可以配一个简单的Restarton-failure[Service] Userhbase ExecStart/opt/hbase/bin/hbase regionserver start Restarton-failure RestartSec10 LimitNOFILE1048576这样即使进程真的abort了10秒后会自动拉起能大幅缩短故障时间。另外HBase 2.4.12中如果开启了HBase自带的hbase.regionserver.thread.global.compaction注意不要让它和Compaction相关线程数设置过大否则频繁Compaction也会引发文件句柄和IO压力。遇到文件句柄类问题时可以把hbase.regionserver.hfile.cleanup.threads适当调大默认2加快文件句柄释放速度。4.3 监控告警和日常巡检建议一个无法回避的真相是RegionServer“自主消失”往往不是一蹴而就的。文件句柄是慢慢涨上去的GC停顿是逐渐变长的堆外内存是一点一点累积的。如果等进程消失才去处理说明监控没有到位。我建议在监控系统里至少要加以下几类指标进程存活RegionServer进程数量、jps检测、Web UI存活节点数。这个最简单但最基础。文件描述符通过JMX的java.lang.management.OperatingSystemMXBean里的OpenFileDescriptorCount指标监控当超过总限制的80%时告警。GC停顿通过GC日志解析或通过JMX的GarbageCollectorMXBean获取CollectionTime的增量。重点看Full GC次数和最长停顿时间。ZooKeeper会话超时Master日志里出现expired关键字就告警。进程的物理内存和系统级内存不仅要看JVM堆还要看RES常驻内存是否会持续增长判断是否存在堆外内存泄漏。日常巡检时我会定期执行一条“组合拳”命令快速筛查所有RegionServer的健康状态for host in rs-01 rs-02 rs-03 rs-04 rs-05; do echo $host ssh $host jps -l | grep HRegionServer; uptime; free -g | head -2; df -h /data | tail -1 done一次执行就能看到进程是否存在、系统负载、内存和磁盘情况。简单粗暴但确实管用。5. 常见问题速查表与排查口诀5.1 症状原因对照表我把这些年在多个版本上遇到过的“RegionServer自主消失”现象做了个汇总按症状对号入座比从日志里大海捞针快得多症状典型日志/现象主要原因优先检查项进程没了无任何日志dmesg里有Out of memory: Kill process java系统OOM Killer物理内存、堆外内存、同机其他服务进程没了日志里有OutOfMemoryError: Java heap space堆内存溢出MemStore/BlockCache占用过高、region迁移热点JMX堆内存曲线、存活对象分布进程没了日志里有OutOfMemoryError: Direct buffer memory堆外内存耗尽堆外内存泄漏、MaxDirectMemorySize过小NMT输出、Netty相关配置进程还在Master标记expired日志里有长GCGC停顿超过ZK会话超时G1 Full GC过长、堆过大GC日志、zookeeper.session.timeout进程没了日志里有Too many open files文件句柄耗尽连接数过多、句柄泄漏lsof -p {pid}、limits配置进程没了日志里有Connection reset by peer网络异常网络抖动、防火墙策略ping、traceroute、网卡丢包进程没了日志里有Could not append to WAL磁盘或句柄问题磁盘满、WAL目录IO异常df -h、iostat这张表不是万能的但能帮你快速收缩排查范围。我见过很多同学对着日志里的一行ERROR纠结半天其实只要按表里的优先级去查大概率能在半小时内定位到根因。5.2 踩坑经验与后续优化建议最后分享几个我在实际排障中总结出来的“土办法”不一定写在官方文档里但很实用。第一问题没定位前不要急着重启RegionServer。很多人一看RegionServer挂了第一反应就是“先拉起来再说”。但你不知道它为什么挂拉起来之后大概率还会再挂。更合理的做法是保留现场把日志、系统消息、GC日志、Master日志先复制下来再做处置。第二进程刚挂的时候/proc/{pid}目录可能还在几秒钟。如果发现得够快可以直接执行ls -l /proc/{pid}/fd | wc -l cat /proc/{pid}/limits这些数据在进程消失后就永远拿不到了。所以遇到这种故障我给自己定的规矩是登录节点的第一件事不是看日志而是先抢救/proc里的信息。第三2.4.12的堆外内存问题不要靠猜要用工具量化。JDK 8以后支持jcmd的NMTNative Memory Tracking功能你可以在hbase-env.sh里加上-XX:NativeMemoryTrackingsummary进程运行时执行jcmd {pid} VM.native_memory summary就能看到堆外内存都分布在哪里。这个在当前版本排障里价值很大尤其是遇到“日志正常、进程被杀”的场景时。第四升级完HBase版本后一定要重新校验操作系统参数。HBase从旧版本升级到2.4.12后JVM参数、GC策略、默认缓冲区的使用可能都变了。以前在2.3.x上“没事”的配置升级后不一定成立。我见过一个集群升级后频繁出现RegionServer假死最后排查出来是旧配置里写死了某个堆大小而新版本默认使用G1GC两者组合后GC停顿暴增。第五关于后续优化如果你长期受困于RegionServer“自主消失”可以考虑往这几个方向做架构改进开启HBase的hbase.regionserver.wal.codec为org.apache.hadoop.hbase.regionserver.wal.ProtobufLogWriter2.4.x默认就是减少WAL写入的IO压力。合理规划region数量。单台RegionServer的region数量建议控制在1000以内超出后文件句柄和内存压力会明显增大。准备一台“冗余”RegionServer节点作为缓冲区。HBase本身就支持将DEAD节点上的region自动负载均衡到其他节点但如果集群没有冗余一个节点挂了之后其他节点会瞬间压力过大进而引发连锁崩溃。回到最开头那个场景。那台“自主消失”的RegionServer最终通过调整ulimit -n参数、优化GC配置、加装文件描述符监控之后半年都没再出现过类似问题。日志里跑出来的根因被写进了排障库后来再有同事遇到类似现象翻一下速查表十分钟就能定位方向。运维HBase就是这样——它不是一个“配好就能跑十年”的系统而是在不断的“消失—排查—修复—预防”循环里慢慢变稳的。希望这篇文章能帮你少走点弯路。

最新新闻

日新闻

周新闻

月新闻