Flink的反压机制

Flink 流处理为什么需要⽹络流控?
Flink V1.5 版之前⽹络流控介绍
Flink V1.5 版之前的反压策略存在的问题
Credit 的反压策略实现原理 Credit 是如何解决 Flink 1.5 之前的问题?
Flink 如何在吞吐量和延迟做权衡?
Flink 反压相关 Metrics 介绍 基于 Flink 的流控机制和反压如何定位 Flink 任务的瓶颈。或者说,如果⼀个平时正常的 Flink 任务突然出现延迟了,怎么来定位问题?到底是 Kafka 读取数据慢,还是中间某个计算环节 ⽐较消耗资源使得变慢,还是由于最后的写⼊外部存储时⽐较慢?
Flink 流处理为什么需要⽹络流控?
分析⼀个简单的 Flink 流任务,下图是⼀个简单的 Flink 流任务执⾏图:任务⾸先从 Kafka 中读取数据、 map 算⼦对数据进⾏转换、 keyBy 按照指定 key 对数据进⾏分区(相同 key 的数据经过 keyBy 后分到 同⼀个 subtask 实例中), keyBy 后对数据接着进⾏ map 转换,然后使⽤ Sink 将数据输出到外部存 储。
众所周知,在⼤数据处理中,⽆论是批处理还是流处理,单点处理的性能总是有限的,我们的单个 Job ⼀般会运⾏在多个节点上,多个节点共同配合来提升整个系统的处理性能。图中,任务被切分成 4 个可 独⽴执⾏的 subtask A0 A1 B0 B1 ),在数据处理过程中,就会存在 shufflfflffle (数据传输)的过 程。例如,subtask A0 处理完的数据经过 keyBy 后发送到 subtask B0 B1 所在节点去处理。 那么问题来了,下图中,上游 Producer 向下游 Consumer 发送数据,在发送端和接受端都有相应的 Send Buffffer 和 Receive Buffffer ,但是上游 Producer ⽣成数据的速率⽐下游 Consumer 消费数据的速 率快。Producer ⽣产数据 2MB/s Consumer 消费数据 1MB/s Receive Buffffer 只有 5MB ,所以过 了5 秒后,接收端的 Receive Buffffer 满了。(可以把下图中的 Producer 当做上⾯案例中的 subtask A0,把下图中的 Consumer 当做上⾯案例中的 subtask B0 ) 下游接收区的 Receive Buffffer 有限,如果上游⼀直有源源不断的数据,那么将会⾯临着以下两个情况:
1. 下游消费者会丢弃新到达的数据,因为下游消费者的缓冲区放不下
2. 为了不丢弃数据,所以下游消费者的 Receive Buffffer 持续扩张,最后耗尽消费者的内存, OOM
程序挂掉
常识告诉我们,这两种情况在⽣产环境都是不能接受的,第⼀种会把数据丢弃、第⼆种会把我们的应⽤ 程序挂掉。所以,该问题的解决⽅案不应该是下游 Receive Buffffer ⼀直累积数据,⽽是上游 Producer 发现下游 Consumer 处理⽐较慢之后,应该在 Producer 端做出限流的策略,防⽌在下游 Consumer 端⽆限制的数据堆积。 那上游 Producer 端该如何做限流呢?可以采⽤下图所示静态限流的策略: 静态限速的思想就是,提前已知下游 Consumer 的消费速率,然后通过在上游 Producer 端使⽤类似令 牌桶的思想,限制 Producer 端⽣产数据的速率,从⽽控制上游 Producer 端向下游 Consumer 端发送 数据的速率。但是静态限速会存在问题:
1. 通常⽆法事先预估下游 Consumer 端能承受的最⼤速率
2. 就算通过某种⽅式预估出下游 Consumer 端能承受的最⼤速率,下游应⽤程序也可能会因为⽹络
抖动、 CPU 共享竞争、内存紧张、 IO 阻塞等原因造成下游应⽤程序的吞吐量降低,然后⼜会出现 上⾯所说的下游接收区的 Receive Buffffer 有限,上游⼀直有源源不断的数据发送到下游的问题, 还是会造成下游要么丢数据,要么为了不丢数据 buffffer 不断扩充导致下游 OOM 的问题 综上所述,我们发现了,上游 Producer 端必须有⼀个限流的策略,且静态限流是不可靠的,于是就需 要⼀个动态限流的策略。可以采⽤下图动态反馈所示:下游 Consumer 端会频繁地向上游 Producer 端进⾏动态反馈,告诉 Producer 下游 Consumer 的负载 能⼒,从⽽ Producer 端动态调整向下游 Consumer 发送数据的速率实现 Producer 端的动态限流。当 Consumer 端处理较慢时, Consumer 将负载反馈到 Producer 端, Producer 会根据反馈适当降低 Producer ⾃身从上游或者 Source 端读数据的速率 来降低向下游 Consumer 发送数据的速率。当 Consumer 处理负载能⼒提升后,⼜及时向 Producer 端反馈, Producer 会通过提升从上游或 Source 端读数据的速率来提升向下游发送数据的速率。通过这个动态反馈来提升整个系统的吞吐量。 补充⼀点,假如我们的 Job 分为 Task A B C Task A Source Task Task B 处理数 据、Task C Sink Task 。假如 Task C 由于各种原因吞吐量降低,会将负载信息反馈给 Task B Task B 会降低向 Task C 发送数据的速率,此时如果 Task B 如果还是⼀直从 Task A 读取数据,那么按照同样的 道理,数据会把 Task B Send Buffffer Receive Buffffer 撑爆,⼜会出现上⾯描述的问题。所以,当 Task B 的 Send Buffffer Receive Buffffer 被⽤完后, Task B 会⽤同样的原理将负载信息反馈给 Task A, Task A 收到 Task B 的负载信息后,会降低 给 Task B 发送数据的速率,以此类推。 上⾯这个流程,就是 Flink 动态限流(反压机制)的简单描述。我们可以看到 Flink 的反压其实是从下游 往上游传播的,⼀直往上传播到 Source Task 后, Source Task 最终会降低从 Source 端读取数据的速 率。如果下游 Task C 的负载能⼒提升后,会及时反馈给 Task B ,于是 Task B
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

꧁꫞ND꫞꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值