
最近,在用Flink SQL批量写HBase,做调度。主要遇到了三个大坑,在接下来的三篇文章中逐个记录。三个大坑分别是,
这篇文章记录一下【HBase Canary报警,Slow Read】这个问题。整个过程及思路如下(我喜欢记录自己的思维过程,总觉得这个才是最值得我们练习的,而且对大家帮助相对于只记录一些程序或者命令要更大),
下面说说其中的一些重要细节。
HBase Region Health Canary报告明细

CM(Cloudera Manager)发现原因:慢查询 Slow Read,HBaseCanary会周期性的抽样查询各个表的数据,以此监控HBase集群的Region的Read性能。

批量写HBase为什么会影响其他HBase表的读
参考之前写的 【Flink】第十四篇:LSM-Tree一般性总结 中的框架图:

在HBase中无非就是磁盘(WAL、StoreFile)、读缓存(BlockCache)、写缓存(memStore)存着我们的数据,注意这里说是写缓存,只是说主要功能是写缓存,但是HBase的读也是会从写缓存中去取数据的,而读缓存是同样,写数据时同样有可能写入BlockCache。
这个也是排除我们分析的可能原因的关键。
分析BlockCache的对于批量写的影响
我们知道BlockCache是RS层面的,一个RS只有一个BlockCache,而如果这个RS上有表的Region正在被批量写,如果BlockCache会被写时存入,那么也一定会影响其他表的数据放入BlockCache,影响了BlockCache的命中率。
基于这样一种思路,又分析了HBase的配置,发现cache on write配置为false,

分析慢查询发生的RS的磁盘IO及网络IO
从CM里分析IO延迟情况如下,

IO延迟的峰值在凌晨3点左右,和报警的时间是一致的,得出结论:批量入数,导致磁盘IO资源紧张,进而导致慢查询。
优化措施
我们知道写HBase会先写WAL,批量这种可re-run的任务如果能用上取消WAL磁盘预写日志那真是很妙了。
查阅HBase官网,看来我的思路没有跑偏:
It is possible to disable the WAL, to improve performance in certain specific situations. However, disabling the WAL puts your data at risk. The only situation where this is recommended is during a bulk load. This is because, in the event of a problem, the bulk load can be re-run with no risk of data loss. The WAL is disabled by calling the HBase client field Mutation.writeToWAL(false). Use the Mutation.setDurability(Durability.SKIP_WAL) and Mutation.getDurability() methods to set and get the field’s value. There is no way to disable the WAL for only a specific table.
http://hbase.apache.org/2.3/book.html#hbase_default_configurations
但是HBase只在API层面允许对每一个Mutation进行控制是否预写日志WAL,所以我们只能修改Flink Hbase Connector或者提issue,于是就有了这个JIRA:
https://issues.apache.org/jira/browse/FLINK-23719
