如何分析及处理Flink反压?

  反压(反压力)是实时计算应用开发中,特别是流式计算中,十分常见的问题。反压意味着数据管道中某个节点成为瓶颈,处理速率跟不上上游发送数据的速率,而需要对上游进行限速。由于实时计算应用通常使用消息队列来进行生产端和消费端的解耦,消费端数据源是基于拉的,所以反压通常是从某个节点传导至数据源并降低数据源(比如卡夫卡消费者)的摄入速率。      关于Flink的反压机制,网上已经有不少博客介绍,中文博客推荐这两篇1。简单来说,Flink拓扑中每个节点(任务)间的数据都以阻塞队列的方式传输,下游来不及消费导致队列被占满后,上游的生产也会被阻塞,最终导致数据源的摄入被阻塞。而本文将着重结合官方的博客[4]分享笔者在实践中分析和处理Flink反压的经验。      反压的影响      反压并不会直接影响作业的可用性,它表明作业处于亚健康的状态,有潜在的性能瓶颈并可能导致更大的数据处理延迟。通常来说,对于一些对延迟要求不太高或者数据量比较小的应用来说,反压的影响可能并不明显,然而对于规模比较大的Flink作业来说反压可能会导致严重的问题。      这是因为Flink的检查点机制,反压还会影响到两项指标:检查点时长和国家大小。      <李类=" Editable-styled public-DraftStyleDefault-unorderedListItem public-DraftStyleDefault-reset public-DraftStyleDefault-depth0 public-DraftStyleDefault-listLTR”>   前者是因为检查点的障碍是不会越过普通数据的,数据处理被阻塞也会导致检查点障碍流经整个数据管道的时长变长,因而检查点总体时间(端到端)持续时间变长。   <李类=" Editable-styled public-DraftStyleDefault-unorderedListItem public-DraftStyleDefault-depth0 public-DraftStyleDefault-listLTR”>   后者是因为为保证EOS (Exactly-Once-Semantics,准确一次),对于有两个以上输入管道的运营商,检查点障碍需要对齐(对齐),接受到较快的输入管道的障碍后,它后面数据会被缓存起来但不处理,直到较慢的输入管道的障碍也到达,这些被缓存的数据会被放到国家里面,导致检查点变大。      这两个影响对于生产环境的作业来说是十分危险的,因为检查点是保证数据一致性的关键,检查站时间变长有可能导致超检查站时失败,而国家大小同样可能拖慢检查点甚至导致伯父(使用基于堆StateBackend)或者物理内存使用超出容器资源(使用RocksDBStateBackend)的稳定性问题。      因此,我们在生产中要尽量避免出现反压的情况(顺带一提,为了缓解反压给检查点造成的压力,社区提出了flip - 76:对齐检查站[4]来解耦反压和检查点)。      定位反压节点      要解决反压首先要做的是定位到造成反压的节点,这主要有两种办法:      <李类=" Editable-styled public-DraftStyleDefault-orderedListItem public-DraftStyleDefault-reset public-DraftStyleDefault-depth0 public-DraftStyleDefault-listLTR”>   通过Flink Web UI自带的反压监控面板;李   <李类=" Editable-styled public-DraftStyleDefault-orderedListItem public-DraftStyleDefault-depth0 public-DraftStyleDefault-listLTR”>   通过Flink任务指标。      前者比较容易上手,适合简单分析,后者则提供了更加丰富的信息,适合用于监控系统。因为反压会向上游传导,这两种方式都要求我们节从源点到水槽的逐一排查,直到找到造成反压的根源原因[4]。下面分别介绍这两种办法。   

  反压监控面板

     Flink Web UI的反压监控提供了子任务级别的反压监控,原理是通过周期性对任务线程的栈信息采样,得到线程被阻塞在请求缓冲区(意味着被下游队列阻塞)的频率来判断该节点是否处于反压状态。默认配置下,这个频率在0.1以下则为好,0.1至0.5为低,而超过0.5则为高。         
        
     图1. Flink 1.8的Web UI反压面板(来自官方博客)      如果处于反压状态,那么有两种可能性:      <李类=" Editable-styled public-DraftStyleDefault-orderedListItem public-DraftStyleDefault-reset public-DraftStyleDefault-depth0 public-DraftStyleDefault-listLTR”>   该节点的发送速率跟不上它的产生数据速率。这一般会发生在一条输入多条输出的运营商(比如flatmap)。   <李类=" Editable-styled public-DraftStyleDefault-orderedListItem public-DraftStyleDefault-depth0 public-DraftStyleDefault-listLTR”>   下游的节点接受速率较慢,通过反压机制限制了该节点的发送速率。

如何分析及处理Flink反压?