Flink生产问题排障-HBaseSink超时

0 阅读5分钟

一、背景与问题

在使用基于Flink技术的实时计算加工场景下,通常都会选择HBase作为维表进行实时关联打宽,另外也会将加工结果实时写入HBase表对外提供实时点查能力。   

本文基于Flink+HBase实时读写的数据链路在生产出现的一次问题,进行排查分析,并定位根因给出解决方案。   

现在有一个Flink生产作业,大致的数据处理链路是Flink实时消费Kafka两个Topic数据进行实时关联后进行聚合统计,将结果写入HBase表对外查询。有一天突然收到该作业的连续告警信息(checkpoint连续失败,即连续2次checkpoint均失败),稍后也有下游反馈HBase表查询的结果不准确。

二、问题排查

问题排查一般都从监控与日志两方面结合,共同定位根因。

1.查看监控:从JM与TM监控看,只发现作业重启次数在增加,其他指标无明显异常。查看checkpoint与task监控,发现checkpoint失败次数不断增加、checkpoint耗时最近都是10min,source算子的inputbuffer一直在增加。

2.查看日志:查看TM处理日志,发现有HBaseSink异常的日志,写入HBase有问题,如下图:

3.查看Flink作业配置的HBase-connector参数如下:

4.对此问题在测试环境成功复现,问题现象与异常日志均能对齐。此表为单region表,同时排查对应HBase Regionserver日志,发现RegionTooBusy异常,如下:

三、问题分析

1.HBase层面   

RegionTooBusy一般发生在数据频繁热点写入,MemStore Flush跟不上数据写入速度,触发此异常(默认MemStore达到128M的4倍大小);此外,若有大批量的putbatch写入且集中在少量region,也会有单次RPC耗时突增后报此错误。   

结合此次问题报错日志,HBase客户端(HBase-connector)报错rpc超时(rpc.timeout默认60s,processingtime120.162s),RegionServer端报错RegionTooBusy,可以推断出大概率是multi.mutation处理耗时慢,客户端不断重试(日志显示重试904次,client.operation.timeout默认120s),引起服务端处理压力骤增,抛出此异常。

2.Flink层面   

此Flink作业是实时join聚合写入HBase的场景,经与开发人员沟通,存在大量回撤流。结合HBase-connector的参数配置,Flink会在1s、2M、1000条数据三个条件中满足任一就触发HBase批量写入。另外在回撤流场景下,Flink中的每条数据都附带一个RowKind类型(+I,-U,+U,-D),Flink的HBase Connector通常被实现为一个UpsertSink,当收到+I或+U消息时,Sink会执行Put操作。如果该行不存在,则插入;如果存在,则覆盖;当收到-D或-U消息时,Sink会执行Delete操作,删除整行数据。当出现回撤时,意味着写入请求的翻倍。

3.逻辑线梳理    

在此Flink实时join聚合写入Hbase的场景下,大量的回撤流每秒产生大量的HBase批量写请求(大几百),频繁的写入请求短时间内集中在个别HBase RegionServer节点,引起频繁的Flush与handle资源消耗,触发RegionTooBusy异常;Flink侧作为HBase客户端不断进行重试,加剧了HBase的资源消耗与处理响应负担,直至超时退出、写入失败。与此同时,FLink定期的checkpoint(默认1min)执行分布式快照期间,也会因为HBase写入阻塞而导致barrier无法继续流动,最后checkpoint超时失败退出,后续陷入恶性循环,不断触发checkpoint连续失败的告警信息。(因FLink作业配置的重启策略与容忍的checkpoint连续失败次数过于容错,未触发阈值停止作业)

四、解决方案

1.Flink层面

    • 调小sink.buffer-flush.max-rows,减少一次批量写入的请求数据条数,避免rpc超时,默认1000能满足大多数常规场景,需根据实际场景充分测试
    • 调大客户端的rpc.timeout与operation.timeout,同时调整HBase重试策略,避免因网络或集群波动产生不必要的超时重试,也需要经过充分测试,过大或过小的配置都会影响整体的稳定性与性能
    • 调整Flink作业的重启策略(失败率策略配置合适的周期与次数,确保能覆盖实际异常场景,实现作业运行整体稳定符合预期,同时遇到极端情况能快速预警与失败,避免影响扩散)

2.HBase层面

    • 对HBase表设计要做好预分区,包括分区规则与数量,避免倾斜与热点
    • 调大RegionServer的handle数量,提升单节点的处理线程池来提高吞吐量(根据机器配置适配调整)
    • 适当增大MemStore大小,让数据在内存中多停留一会儿,减少刷盘频率,从而减轻回撤流导致的磁盘I/O压力
    • 调高hbase.hstore.compaction.min,或者调整hbase.hstore.blockingStoreFiles阈值,避免频繁的阻塞式Compaction

因HBase集群是公共集群,调整服务端配置的成本较大,本问题主要针对Flink层面进行优化调整,经过充分测试重新上线后,作业稳定运行至今,未再次出现类似异常。

五、总结

面对生产问题,我们首先要有清晰的排查思路,然后需要对整个数据链路与涉及的组件运行原理有一定的掌控,才能做到快准狠,迅速定位问题根因与应对处置,提升系统整体的SLA。