在理论运维HBase集群时,各位小伙伴总会遇到RegionServer异样宕机、业务写入提早增大甚至无奈写入等相似问题。本章联合笔者的教训、列举实在生产线环境常见的几个问题,并介绍这些地问题的根本排查思路。同时,重点对HBase零碎中的日志进行梳理介绍,最初对如何通过监控、日志等工具进行问题排查进行总结,造成问题排查套路,不便读者进行实际。

regionserver宕机

案例一: 长时间GC导致Regionserver宕机

长时间FullGC是RegionServer宕机最常见的起因.剖析这类问题,能够遵循如下排错过程:

景象:收到Regionserver过程退出的报警。

1. 宕机起因定位

步骤1: 通常在监控上看不出,须要到事发的RegionServer日志间接搜寻2类关键字---a long garbage collecting pause 或ABORTING region server。对于长时间Full GC的场景,搜寻第一个关键字会检索到:

     2019-06-14T17:22:02.054 WARN [JvmPauseMonitor] util.JvmPauseMonitor: Detected pause in JVM or host machine (eg GC): pause of approximately 20542ms     GC pool 'ParNew' had collection(s): count=1 time=0ms     GC pool 'ConcurrentMarkSweep' had collection(s): count=2 time=20898ms     2019-06-14T WARN [regionserver60020.periodicFlusher] util.Sleeper: We slept 20936ms instead of 100ms, this is likely due to a long garbage collecting pause and it's usually bad, see http://hbase.apache.org/book.html#trouble.rs.runtime.zkexpired

步骤2: 通常CMS GC策略会在2种场景下产生重大的Full GC ,1. Concurrent Mode Failure 2. Promotion Failure。

   2017-06-14T17:22:02.054+0800:21039.790[FulGC20172017-06-14T17:22:020544+0800:21039.790: [CMS2017-06-14T17:22:02.0544+0800:21041.477: [CMS-concurrent-mark:1767/1782 sec][Times: user=14.01 sys=0.00 real=1.79 secs](concurrent mode fallure): 25165780K->25165777K(25165824K), 18.4242160 secs] 26109489K->26056746K(26109568K), [CMS Perm: 48563K-48534K(262144K), 18.4244700s secs][Times: user=28.77 sys=0.00 real=18.42. secs]]   2017-06-14T17:22:20:47340800:21058.215:Totalime for which appll cation threads were stopped:184270530 seconds

当初根本能够确认是因为concurrent mode failure模式的CMS GC导致长时间应用程序暂停。

2. 宕机起因剖析

故障因果剖析: JVM触发的concurrent mode failure模式的CMS GC 会产生长时间的stop the world,下层利用因而长时间暂停。进一步导致RegionServer与Zookeeper之间建设的session超时。session一旦超时,Zookeeper就会告诉Master将此宕机RegionServer踢出集群。

什么是concurrent mode failure模式的GC?为什么会造成长时间暂停?假如HBase零碎正在执行CMS回收老年代空间,在回收的过程中恰好从年老代降职了一批对象进来,不巧的是,老年代此时曾经没有空间再包容这些对象了。这种场景下,CMS收集器会进行工作,零碎进入stop-the-world模式,并且回收算法会进化为单线程复制算法,重新分配整个堆内存的存活对象到SO中,开释所有其余空间。很显然,整个过程会比拟漫长。

3. 解决方案

既然是老年代来不及GC导致的问题,那只须要让CMS收集器更早一点回收就能够大概率防止这种状况产生。
JVM提供了参数
XX:CMSInitiatingOccupancyFraction=N来设置CMS回收的机会, N示意以后老年代已应用内存占年老代总内存的比例, 能够将值改得更小使回收更早进行,比方60

另外倡议在解决时关注下零碎BlockCache是否开启了offheap模式,还有JVM启动参数是否正当,JVM堆内存治理是否未正当应用堆外内存。

案例二: 零碎重大Bug导致Regionserver宕机

大字段scan导致RegionServer宕机

景象: RegionServer过程退出

1. 宕机起因定位

步骤1: 日志。先查看GC相干,如果没有再持续搜寻关键字“abort”,查到可疑日志“java.lang.OutOfMemoryError: Requested array exceeds VM limit"

步骤2: 源码确认。看到带堆栈的FALTAL级别日志,定位到源码或者依据在关键字在网上搜寻,确认该异样产生在scan后果数据在回传给客户端时,因为数据量太大导致申请的array大小超过JVM规定的最大值(Interge.Max_Value-2)

2. 故障因果剖析

因为HBase零碎本身的bug,在某些场景下scan后果数据太大导致JVM在申请array时抛出OutOfMemoryError,造成RegionServer宕机

3. 实质起因剖析

造成这个问题能够认为是HBase的bug,不应该申请超过JVM规定阈值的array。另一方面,也能够认为是业务方用法不当。

  • 表列太宽,并且对scan后果没有做列数据限度,导致一行数据就可能因为蕴含大量列而超过array阈值
  • KeyValue太大,并且没有对scan的返回做限度,导致返回数据后果大小超过array阈值。

4. 解决方案

能够在服务端做限度 hbase.server.scanner.max.result.size 大小
也能够在客户端拜访的时候对返回后果大小做限度(scan.setMaxResultSize)

hbase写入异样

案例:HDFS缩容导致局部写入异样

景象:业务反馈局部写入申请超时异样。此时HBase在执行HDFS集群多台DataNode服役操作。

1. 写入异样起因定位

步骤1: 实践上平滑服役不会造成下层业务感知

步骤2: 排查HBase节点集群监控, 发现服役操作期间节点IO负载较高

初步判断写入异样和退服期间IO负载较高有肯定关系。

步骤3:在相干工夫点查看RegionServer日志,搜寻“Exception”,失去要害的2行:

 2020-04-24 13:03:16,685 WARN [ResponseProcessor for block BP-1655660372-10.x.x.x-1505892014043:blk_1093094354_19353580] hdfs.DFSClient: DFSOutputStream ResponseProcessor exception for block BP-1655660374-10.x.x.x-1505892014043:blk_1093094354_19353580 java.io.IOException: Bad response ERROR for block BP-1655660372-10.x.x.x-1505892014043:blk_1093094354_19353580 from datanode 10.x.x.x:50010 at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer$ResponseProcessor.run(DFSOutputStream.java:828) 2020-04-24 13:03:16,700 INFO [sync.0] wal.FSHLog: Slow sync cost: 13924 ms, current pipelin: [10.x.x.x:50010, 10.x.x.x:50010]

HLog执行sync破费工夫太长(13924ms), 写入响应阻塞。

步骤4: 进一步查看了DataNode日志发现刷盘很慢,有异样信息

2020-04-24 13:03:16,686 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: newsrec-hbase10.dg.163.org:50010:DataXceiver error processing WRITE_BLOCK operation src: /10.x.x.x:55637 dst:10.x.x.x:50010

2. 写入异样起因剖析

  • 多台DataNode同时服役,过程中copy大量数据块会导致集群所有节点的带宽和IO压力陡增。
  • 节点IO负载很高导致DataNode执行数据块落盘很慢,进而导致HBase中HLog刷盘超时异样,在集群写入压力较大的场景下会引起写入沉积超时

3. 解决方案

  • 运维应在业务低峰期执行DataNode服役操作
  • 不能同时服役多台DataNode,免得造成短时间IO压力急剧增大,改成顺次服役。

hbase运维时问题剖析思路

生产线问题是零碎运维工程师的导师。之所以这样说,是因为对问题的剖析能够让咱们积攒更多的问题定位伎俩,并且让咱们对系统的工作原理有更加深刻的了解,甚至接触到很多之前不可能接触到的常识畛域。就像去一个 未知的世界摸索一个未知的问题,越往里面走,就越能看到他人看不到的世界。所以生产线上的问题产生了,肯定要抓住机会,追根溯源。毫不夸大地说,技术人员的外围能力很大部分体现在定位并解决问题的能力上。

实际上,解决问题只是一个后果。从收到报警看到问题的那一刻到最终解决问题,必然会经验三个阶段: 问题定位,问题剖析,问题修复。 问题定位是从问题登程通过肯定的技术手段找到触发问题的实质,问题剖析是从原理上对整个流程脉络梳理分明,问题解决依赖于问题剖析,依据问题剖析的后果对问题进行针对性修复或全局修复。

1. 问题定位

定位问题的触发起因是解决问题的要害。问题定位的根本流程如图:

  • 指标监控剖析。很多问题都能够间接在监控界面上直观地找到答案。比方业务反馈在某一时刻后读提早变得十分高。第一反馈是去查看零碎IO、CPU或者带宽是不是有任何异样,如果看到IO利用率在对应工夫点变得异样高,就根本能够确认读性能降落就是由此导致。虽说IO利用率不是实质起因,但这是问题链上的 重要一环,接下来探索为什么IO利用率在对应工夫点异样。

对问题定位有用的监控指标十分多,宏观上看能够分为零碎根底指标和业务相干指标两大类。零碎根底指标包含零碎IO利用率、CPU负载、带宽等;业务相干指标包含RegionServer级别读写TPS、读写均匀提早、申请队列长度/Compaction队列长度、MemStore内存变动、BlockCache命中率等。

  • 日志剖析。对于零碎性能问题,监控指标或者能够帮忙,但对于零碎异样类型的问题,监控指标可能看不到端倪。这个时候HBase零碎相干日志最外围的有RegionServer日志和Master日志,另外GC日志、HDFS相干日志(NameNode日志和DataNode日志)以及Zookeeper日志在特定场景下对剖析问题都有帮忙。

对于日志剖析并不需要将日志从头到尾读一遍,能够间接搜寻相似于“Exception”,“ERROR”,甚至“WARN”关键字,再联合时间段对日志进行剖析。

  • 网络求助。通过监控指标剖析和日志剖析后,运维人员通常都会有播种。也有局部状况下,咱们能看到了"Exception",但不明确具体含意。此时须要去网络上求助。首先在搜索引擎上依据相干日志查找,大多数状况下都能找到相干的文章阐明,因为你遇到的问题很大概率他人也会遇到。如果没有线索,接着去各个业余论坛查找求教,比方stackoverflow、hbase-help.com以及各种HBase相干交换群组。最初,还能够发邮件到社区求教社区技术人员。
  • 源码剖析。在问题解决之后,倡议通过源码对问题进行再次确认

2. 问题剖析

解决未知问题就像一次摸索未知世界的旅程。定位问题的过程就是向未知世界走去,走得越远,看到的货色越多,见识到的世面越大。然而目迷五色的风景如果不认真捋一捊,一旦他人问起那个中央怎么样,必然会无言以对。

问题剖析是问题定位的一个逆过程。从问题的最实质起因登程,联合零碎的工作原理,一直推演,最终推演出零碎的异样行为。要把这个过程剖析的清清楚楚,不仅仅须要监控信息、异样日志,更须要联合零碎工作原理进行剖析。所以回过头来看,只有把零碎的原理了解分明,能力把问题剖析分明。

3. 问题修复

如果可能把问题的前因后果解释分明,置信就可能轻而易举地给出针对性解决方案。这应该是整个问题摸索中最轻松的一个环节。没有解决不了的问题,如果有,那就是没有把问题剖析分明。

参考: 《HBase 原理与实际》


作者:许佳宾|Growing运维施行工程师
专一于平台施行、sla治理/工具建设、Devops开发