HBase 线上问题排查 - 为什么读写这么少还会触发巨量 IO ?

前言

之前的文章都是偏环境的部署、搭建、测试以及一些官文翻译,实在是没有什么硬货,现在部分业务开始上生产,那么稳定性就是首当其冲的。最近负责排查了一个线上关于 HBase 的问题,特别来分享下思路。

我湾使用的是 Cloudera Manager 来管理 CDH 相关组件,所以以下涉及的操作都是在 Cloudera Manager 里完成的,包括监控、参数调优等。因为项目涉密所以很多线上环境的截图我就不方便发了,但是会尽量阐述的易懂。

问题发现

我湾的报警是通过 nagios 周期回调脚本进行的,上周开始频繁收到类似如下报警:

HBASE_REGION_SERVERS_HEALTHY=CONCERNING(服务健康处于关注状态)。

不得不说 Cloudera Manager 报警抽象的不错,我们可以通过整体健康度去关注一个服务。然后我去线上看了看,发现是 flush queue size 达到 warning 阈值,默认是 10。这个监控项的意义在于,告诉运维人员,memstore 刷内存太猛了,queue 积压了。

问题分析

只要你理解 memstore 刷内存的触发机制(不清楚的可以去补补课、看看代码),就可以知道导致这个问题的原因大致如下:

  • A: 写入太频繁量又大,的确需要产生那么多 flsuh task,IO 处理跟不过来(包括 disk 和 network),这种情况下会触发持续的 flush 波峰,加上文件数增加触发 compaction,那么就会严重,要么客户端做优化要么服务端做扩容(视情况而定可能需要迁移至 SSD 集群或者上万兆网卡);
  • B: 写入太频繁但是量一般,写入很均匀,几乎所有的 region 下的 store 都在一个时间点达到刷写阈值(hbase.hregion.memstore.flush.size,默认是 128 MB),这种情况下会触发类似锯齿状的 flush 波峰;
  • C: 写入不频繁,量也很少,由于其他问题导致 IO、network 等资源吃紧间接产生积压;

反观线上生产监控,我发现 TPS(写入吞吐)非常小,也就 10 不到,QPS(读吞吐)也很小,不到100,吞吐量也都很小,那么就排除了 A 情况。查看生产日志(regionserver的日志),发现有很多类似如下的输出:

... because info has and old edit so flush to free WALs after random delay ...

这是很明显的写入量很小,因为周期性 flush 线程触发的行为,比如某 store 很久没更新了而最新的 edit 距今超过阈值(默认 1小时),那么就会 delay 一个 random 时间去执行刷新。我通过如下关键字去看历次触发的 flush 产生的文件大小:

grep 'org.apache.hadoop.hbase.regionserver.HStore: Added hdfs' /home/admin/logs/hbase/hbase-cmf-hbase-REGIONSERVER-${FQDN_HOSTNAME}.log.out | awk -F 'filesize=' '{print$2}'

发现几乎每次刷出来的都是小文件,不到 100KB,由此可以排除情况 B。

好,接下来看看,是什么间接导致我们的 flush queue 积压呢?运维看监控有一个绝招是说,看对应时间点的指标趋势,我看到对应有高峰的时间点之前几分钟,都会来一波巨量的 compaction,同时做 compaction 的时候对应的日志里看到 flush 出来的文件的确有超过 100MB 的情况,并且是所有机器基本同时有这样的刷写(也就是基本达到了 hbase.hregion.memstore.flush.size,看起来个别 store 是符合情况 B的)。因为我们只有 3 个SATA 节点,所以 100MB 的刷写还是有点儿难受的,因为三份冗余,我们实际会产生 100MB 的读、300MB 的写,产生 400MB 的流量,每次触发高峰的时候都是 3 台机器基本同时 flush 出 100MB + 的文件,从而导致海量 compaction。

所以,问题的原因为:

多台机器同时刷出 100MB + 的 store file 文件 -> 多台机器同时因为文件数达到阈值(默认是 3 )触发 compaction -> 3份冗余产生 IO Storm -> flush queue 随之积压。

解决方案

知道问题的根源就好办事儿了,在这样的情况下,文件数量肯定不是问题(也就是不会影响读性能,或者说 QPS 这么少,担心啥呢?)我就简述一下我的方案,利用 PressureAwareCompactionThroughputController 限制业务高峰期(10:00-21:00)时的 compaction 流量,减少 IO 波峰,缓解 flush queue 积压。其中业务高峰期很好判断,查看 Cloudera 相关监控指标就知道,啥时候写入比较少了,我们的业务是在晚上21点后就基本没有流量了。

关于 PressureAwareCompactionThroughputController

相应的算法如下:

  • 如果 compaction 压力大于 1.0,不进行限流;

  • 在非高峰期,使用固定吞吐进行限流,对应配置 hbase.hstore.compaction.throughput.offpeak, hbase.offpeak.start.hourand hbase.offpeak.end.hour

  • 在平时(也就是高峰期),最大吞吐在 hbase.hstore.compaction.throughput.higher.boundhbase.hstore.compaction.throughput.lower.bound 之间进行调整,(默认值分别为 20 MB/sec 和 10 MB/sec),并且 compactionPressure 在 0.0 ~ 1.0 之间,使用以下的公式进行限流。compactionPressure 表示 需要做 compaction 的 store files 个数。

    lower + (higer - lower) * compactionPressure

那么 compactionPressure 到底是怎么得到的?看了一下 Store.getCompactionPressure() 这个方法,是这么说的:

该值表述的是某个 store 需要做 compaction 的紧急程度。必须大于等于 0.0 ,也就是正数,任何大于 1.0 的数值表示我们有过多 store files。

  • 如果 getStorefilesCount <= getMinFilesToCompact 返回 0.0;
  • return (getStorefilesCount - getMinFilesToCompact) / (blockingFileCount - getMinFilesToCompact);

对于 striped stores,我们必须根据各个 strip 分区的最大值得到最终全局最大的值。

有关 stripe compaction 可以参考这里

getStorefilesCount() 返回的是某个 store 下的 store files 数量,getMinFilesToCompact() 返回的是 minor compaction 包含的文件数量下限,默认为 3;blockingFileCount 表示的是达到这个数值的话阻塞该 store 的写入直至 compaction 完成后文件数小余该数值,默认为 7。

看起来,某 store 只要文件数在 3 ~ 7 个的时候,就会触发限流,认为即使不做 compaction 或者慢慢做,都不会因为文件数过多,极大影响读性能。对于线上集群,getMinFilesToCompact 是 3、blockingFileCount 是 7,平均 store files 长期在 2.8 左右,可以考虑通过该方案 smooth compaction 流量

方案测试

调整 HBase 配置,分为三组限流进行写入压力测试(测试工具是 HBase Load Test Tool),目标是查看不同的阈值对 compact rate、disk io、network io 的影响。

测试环境:

公司日常测试集群,配置为 6core 16GB 内存 SATA。

测试指令如下:

hbase ltt -tn TestTable -write 10:1000 -num_keys 1000000

配置大致如下:

<property>
    <name>hbase.regionserver.throughput.controller</name>
    <value>org.apache.hadoop.hbase.regionserver.compactions.PressureAwareCompactionThroughputController</value>
    <discription>使用压力感知compaction限流策略控制器</discription>
</property>
<property>
    <name>hbase.hstore.compaction.throughput.higher.bound</name>
    <value>${HIGHER_BOUND}</value>
    <discription>限流上限阈值</discription>
</property>
<property>
    <name>hbase.hstore.compaction.throughput.lower.bound</name>
    <value>${LOWER_BOUND}</value>
    <discription>限流下限阈值</discription>
</property>
<property>
    <name>hbase.hstore.compaction.throughput.offpeak</name>
    <value>9223372036854775807</value>
    <discription>非高峰期阈值,为Long.MAX即不限流</discription>
</property>
<property>
    <name>hbase.offpeak.start.hour</name>
    <value>21</value>
    <discription>非高峰期开始小时时刻</discription>
</property>
<property>
    <name>hbase.offpeak.end.hour</name>
    <value>8</value>
    <discription>非高峰期结束小时时刻</discription>
</property>
<property>
    <name>hbase.hstore.compaction.throughput.tune.period</name>
    <value>60000</value>
    <discription>限流调整周期,单位毫秒</discription>
</property>

对比组有三个:

  • A 组,hbase.hstore.compaction.throughput.higher.bound 为 1MB,hbase.hstore.compaction.throughput.lower.bound 为 512 KB;
  • B 组,hbase.hstore.compaction.throughput.higher.bound 为 10MB,hbase.hstore.compaction.throughput.lower.bound 为 5MB;
  • C 组,hbase.hstore.compaction.throughput.higher.bound 为 100MB,hbase.hstore.compaction.throughput.lower.bound 为 50MB;(对于千兆网卡、SATA盘来说已经相当于没有什么限制了,可以当做空白组进行对比)

我们比较三组的 compact rate、disk io、network io,分别如下:

compact rate(A B C 自上而下):

compact_rate_1M_512KB
compact_rate_10M_5M
compact_rate_100M_50M

disk io(A B C 自上而下):

disk_io_1M_512KB
disk_io_10M_5M
disk_io_100M_50M

network io(A B C 自上而下):

network_io_1M_512KB
network_io_10M_5M
network_io_100M_50M

测试结论

在对读影响较小的(文件数不超过 blockingFileCount)情况下,PressureAwareCompactionThrottle 可以有效平滑 compaction 带来的流量、磁盘 IOPS 冲击。

测试的三组里,A、B 组 有部分情况下没有符合限流预期是因为局部 store 文件数过多导致,属于合理。B、C 组没有明显区别是因为三台虚拟机节点写入吞吐已经在 B 组基本达到瓶颈,所以有价值的比较是 A、B 两组。

小结

我坚持授人以渔,运维去解决线上问题的时候,必须要确定问题的根源对症下药,而非一知半解去看待,否则这个雷还在,只会越治理越乱。我们必须对开源产品要有足够的把控力,看源码、理解架构是非常有必要的,对自己的定位切记不能只是一个只会部署、重启的 ops,那最终只会被 devops 替代。同样的,我也不认为运维只有 devops 或者 SRE 一条路去走,只要熟悉生态,勤于学习不同的优秀架构和数据结构,一通则全通,甚至在开发工程师没有解决思路的时候提供有效解决方案,在架构设计的时候提出自己有效的建议,至少我会坚持在架构这条路上,当初选择放弃钻研代码,那么现在爬也会爬完(当然,读代码的能力是必须要有的)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 最近在逐步跟进Hbase的相关工作,由于之前对Hbase并不怎么了解,因此系统地学习了下Hbase,为了加深对Hb...
    飞鸿无痕阅读 50,176评论 19 271
  • Hbase架构与原理 HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang所撰写的Goo...
    全能程序猿阅读 86,278评论 2 37
  • HBase存储架构图 HBase Master 为Region server分配region 负责Region s...
    kimibob阅读 5,564评论 0 52
  • HBase那些事 @(大数据工程学院)[HBase, Hadoop, 优化, HadoopChen, hbase]...
    分痴阅读 3,925评论 3 17
  • 原创文章,转载请注明原作地址:http://www.jianshu.com/p/0f9578df7fbc 一. 架...
    EchoZhan阅读 15,129评论 4 33