马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
1. 什么是 Flink 反压和 TCP 流控制?
反压(Backpressure)是什么?
反压是分布式流处置惩罚体系中一种自我调治机制。当卑鄙处置惩罚数据的速率跟不上上游发送数据的速率时,反压会让上游放慢发送速率,以制止体系过载乃至瓦解。简朴来说,就像水管里水流太快,卑鄙接不住,上游就得“憋一憋”。
在 Flink 中,反压是内置的特性,重要通过其数据传输机制和网络层来实现。它确保整个数据处置惩罚管道(Pipeline)的稳定性。
TCP 流控制是什么?
TCP 流控制是 TCP 协议的一部门,用来协调发送端和吸收端的数据传输速率。Flink 的反压机制依靠底层的 TCP 流控制,通过 TCP 的“滑动窗口”机制实现动态调整。滑动窗口就像一个“水龙头开关”,控制发送端一次能发多少数据。
Flink 反压和 TCP 流控制的关系
Flink 的反压并不是直接在应用层手动实现的,而是使用了 TCP 协议的天然流控本领。当 Flink 的卑鄙 Task 消费变慢时,TCP 的吸收缓冲区会变满,导致发送端被壅闭,从而实现反压。
2. 为什么须要反压?
想象你在流水线上装瓶子,上游呆板每秒生产 100 个瓶子,但卑鄙只能每秒装 50 个。如果不减慢上游,瓶子会堆积,终极生产线瓦解。反压的作用就是让上游知道卑鄙的瓶子装不下了,自动减速到每秒 50 个,保证整个体系安稳运行。
在 Flink 中:
- 数据倾斜:某个 Task 处置惩罚慢。
- 资源不敷:CPU、内存不够。
- 卑鄙算子复杂:好比窗口盘算、Join 利用耗时长。
这些都会导致卑鄙变慢,反压就派上用场。
3. 发生场景
反压通常发生在以下环境:
- 卑鄙处置惩罚速率慢:好比某个 Task 因为复杂盘算(聚合、排序)变慢。
- 网络瓶颈:TaskManager 之间的网络传输速率不够。
- 资源竞争:多个 Task 抢占 CPU 或内存,导致某 Task 被拖慢。
- 外部体系延长:好比卑鄙写入 Kafka、数据库时壅闭。
举个例子:假设一个 Flink 作业读取日志 流(上游每秒 1 万条),卑鄙要做及时统计(好比按分钟聚合)。如果卑鄙算子处置惩罚不外来,反压就会触发。
4. Flink 反压怎么做?底层原理和步调推导
Flink 的反压机制依靠 TCP 和其内部缓冲池(Buffer Pool)机制。我们一步步拆解,从底层到源代码层面推导。
步调 1:数据传输的根本单元——Network Buffer
Flink 的数据在 TaskManager 之间通过网络传输,数据被切成小块,放入 Network Buffer(网络缓冲区)。每个 Buffer 是一个固定巨细的内存块(默认 32KB)。
- 原理推导:上游 Task 天生数据后,序列化成字节流,填入 Buffer。Buffer 满了就通过网络发给卑鄙。
- 源代码:在 org.apache.flink.runtime.io.network.buffer.NetworkBufferPool 中,Flink 管理这些 Buffer 的分配和接纳。
步调 2:卑鄙吸收数据——TCP 吸收缓冲区
卑鄙 TaskManager 通过 TCP Socket 吸收这些 Buffer。TCP 协议有一个 吸收缓冲区(Receive Buffer),巨细由利用体系和 JVM 参数决定(好比 SO_RCVBUF)。
- 原理推导:卑鄙 Task 从吸收缓冲区读取 Buffer 并处置惩罚。如果卑鄙处置惩罚慢,吸收缓冲区里的数据就被“堆积”起来。
- 普通比喻:卑鄙像个“吃货”,吃得慢,盘子(吸收缓冲区)就满了。
步调 3:TCP 滑动窗口变小
TCP 使用滑动窗口(Sliding Window)控制发送速率。窗口巨细由吸收端的可用缓冲区空间决定。
- 原理推导:
- 卑鄙吸收缓冲区满了,告诉上游:“我没地方存了,窗口巨细变成 0。”
- 上游的 TCP 发送端收到窗口巨细为 0 的通知,停息发送。
- 底层细节:这是 TCP 协议的行为,Flink 不须要本身实现,在 java.nio.channels.SocketChannel 的底层依靠中表现。
步调 4:Flink 的发送端壅闭
上游 Task 在发送 Buffer 时,调用的是 SocketChannel.write()。当 TCP 发送缓冲区(Send Buffer)也满时,write() 利用会壅闭。
- 原理推导:发送端壅闭后,上游 Task 的线程被挂起,数据天生速率天然减慢。
- 源代码:在 org.apache.flink.runtime.io.network.netty.NettyBufferPool 中,Flink 使用 Netty 管理网络传输,壅闭行为由 Netty 的 Channel 实现。
步调 5:反压向上流传
Flink 的使命是链式实行的(Task Chain)。上游 Task 壅闭后,它前面的 Task 因为输出被堵住,也会变慢,终极反压传到数据源(Source)。
- 原理推导:Source 好比 Kafka Consumer,读取速率会因为卑鄙壅闭而减慢(取决于具体实现,好比 Kafka 的 fetch.max.bytes 参数)。
- 普通比喻:整条流水线像多米诺骨牌,背面卡住,前面全慢。
完整流程总结
- 卑鄙处置惩罚慢 → 吸收缓冲区满。
- TCP 窗口缩小 → 上游发送壅闭。
- 上游 Task 停息 → 反压传到 Source。
整个过程不须要 Flink 手动干预,完全依靠 TCP 的自适应本领。
5. 源代码层面的关键点
以下是 Flink 中与反压相关的焦点类和逻辑:
- NetworkBufferPool:管理 Buffer 的分配。
- 方法:requestBuffer() - 当没有可用 Buffer 时,发送端会等候。
- NettyPartitionRequestClient:负责 TaskManager 间的数据传输。
- 方法:requestNextBuffer() - 卑鄙读取变慢时,影响上游发送。
- Task:Flink 的实行单元。
- 方法:invoke() - Task 的主循环,壅闭时停息实行。
这些类通过 Netty 和 Java NIO 的底层实现,间接使用 TCP 的流控。
6. 非专业人士怎么明白?
把 Flink 反压想象成一个快递体系:
- 上游:快递员不绝打包包裹(数据)。
- 网络:快递车运输包裹(TCP)。
- 卑鄙:收货人拆包裹(处置惩罚数据)。
如果收货人拆得慢,快递车塞满包裹停在门口,快递员就得停下打包。反压就像快递员接到通知:“别送了,车没地方了!”
7. 怎样监测和办理反压?
监测
- Flink Web UI:查察 Backpressure 状态(OK, LOW, HIGH)。
- 指标:bufferUsage 和 networkLatency。
办理
- 增长并行度:让卑鄙多几个人干活。
- 优化算子:镌汰复杂盘算。
- 调整缓冲区:增大 taskmanager.network.memory 参数。
|