Flink学习笔记:反压
今天来聊在 Flink 运维过程中比较常见的一个问题:反压。什么是反压
反压是流式系统中关于数据处理能力的动态反馈机制,并且是从下游到上游的反馈,一般发生在上游节点的生产速度大于下游节点的消费速度的情况。
数据如何传输
在了解反压的细节之前,首先要知道 Flink 中数据是如何传输的。在 Flink 中,两个算子之间的关系分为三种:
[*]部署在同一个 TaskManager 上,且属于同一算子链。
[*]部署在同一个 TaskManager 上,但不是同一个算子链。
[*]部署在不同的 TaskManager 上。
三种不同的关系,对应的算子间的数据传输方式也不同。先说第一种。
同一线程数据传输
同一线程中的两个算子共享内存,因此数据传输非常简单,上游产出好数据后,直接调用下游的 processElement 方法即可。
本地线程数据传输
对于第二种关系,两个算子不在同一线程,但是部署在同一个 TaskManager 上,也就是算子之间的数据传输是跨线程的。我们通过一个图来解释。
图中,Flat Map Task 是上游算子,sum 是下游的算子。它们共享一块 Buffer 内存。当 Buffer 中没有数据可以消费时,sum 所在的线程会阻塞(步骤1)。随着数据的流入,Flat Map Task 会将处理好的数据写入到 ResultSubpartition(步骤2),然后 flush 到 Buffer 中(步骤3)。此时会唤醒 sum 所在的线程(步骤4),它就可以从 Buffer 中读取数据了(步骤5)。
远程数据传输
第三种跨 TaskManager 的数据传输,与第二种类似,不过也有些区别。我们还是通过一张图来解释。
从图中可以看到,当 sum 所在线程没有 Buffer 可以消费时,会通过 PartitionRequestClient 向 Flat Map Task 所在的进程发送请求。Flat Map Task 所在进程接收到请求后,会读取 Buffer 中的数据并返回。
Flink 的反压
了解了 Flink 的数据传输方式之后,我们再来看下 Flink 是如何感知反压的。
上图是一个数据传输的简图。当 Task1 有 Buffer 空间时,记录 A 被序列化并写入 LocalBufferPool 中,接着发送到 Task2 的 LocalBufferPool 中,Task2 读取并反序列化后交由程序处理。
这里我们也分两个场景讨论。
本地传输
Task1 和 Task2 在同一个 TaskManager 节点,Task1 和 Task2 共用 Buffer,一旦 Task2 消费了 Buffer,该 Buffer 就会被回收。如果 Task2 的处理速度比 Task1 慢,那么 Buffer 的回收速度就赶不上 Task1 取 Buffer 的速度,这样会导致无 Buffer 可用,最终 Task1 就会降速。
远程传输
Task1 和 Task2 运行在不同的 TaskManager 上,那 Buffer 会发送到网络后,等接收端消费完再回收。在发送端,会通过 Netty 水位机制来保证不往网络中写太多数据,如果网络中的数据超过了高水位值,就会等其下降到低水位值以下才会继续写数据。如果网络有堆积,发送端就会暂停发送,Buffer 也不会被回收,这就会阻塞 writer 往 ResultSubPartition 中写数据。
反压监控
在 Flink Web UI 中,可以找到反压的监控
它有三种状态:
<ul>OK: 0% 东西不错很实用谢谢分享 感谢发布原创作品,程序园因你更精彩 感谢,下载保存了 这个有用。 谢谢分享,试用一下 谢谢分享,辛苦了 懂技术并乐意极积无私分享的人越来越少。珍惜 感谢分享,学习下。 过来提前占个楼 东西不错很实用谢谢分享 这个有用。 这个好,看起来很实用 这个好,看起来很实用 谢谢楼主提供! 收藏一下 不知道什么时候能用到 前排留名,哈哈哈 谢谢分享,试用一下 懂技术并乐意极积无私分享的人越来越少。珍惜 感谢发布原创作品,程序园因你更精彩
页:
[1]
2