【译】A Deep-Dive into Flink's Network Stack(1)
- 2019 年 10 月 4 日
- 筆記
Flink的网络堆栈是组成flink-runtime模块的核心组件之一,是每个Flink工作的核心。 它连接所有TaskManagers的各个工作单元(子任务)。 这是您的流式传输数据流经的地方,因此,对于吞吐量和您观察到的延迟,Flink作业的性能至关重要。 与通过Akka使用RPC的TaskManagers和JobManagers之间的协调通道相比,TaskManagers之间的网络堆栈依赖于使用Netty的低得多的API。
这篇博文是关于网络堆栈的一系列帖子中的第一篇。 在下面的部分中,我们将首先深入了解流操作符所呈现的抽象,然后详细介绍Flink的物理实现和各种优化。 我们将简要介绍这些优化的结果以及Flink在吞吐量和延迟之间的权衡。 本系列中的未来博客文章将详细介绍监控和指标,调整参数和常见的反模式。
逻辑视图
Flink的网络堆栈在相互通信时为子任务提供以下逻辑视图,例如在keyBy()要求的网络混洗期间。

它抽象了以下三个概念的不同设置:
- 子任务输出类型(ResultPartitionType):
- 流水线的(有界的或无界的):一旦产生数据就可以向下游发送,可能是一个接一个地,作为有界或无界的记录流。
- 阻塞:仅在生成完整结果时向下游发送数据。
- 调度类型:
- 一次性(急切):同时部署作业的所有子任务(用于流应用程序)。
- 第一个输出的下一个阶段(懒惰):一旦任何生产者生成输出,就立即部署下游任务。
- 完整输出的下一个阶段:当任何或所有生产者生成完整输出集时,部署下游任务
- 传输:
- 高吞吐量:Flink不是一个一个地发送每个记录,而是将一堆记录缓冲到其网络缓冲区中并完全发送它们。这降低了每个记录的成本并导致更高的吞吐量。
- 通过缓冲区超时的低延迟:通过减少发送未完全填充的缓冲区的超时,您可能会牺牲吞吐量来延迟
我们将在下面的部分中查看吞吐量和低延迟优化,这些部分将查看网络堆栈的物理层。 对于这一部分,让我们详细说明输出和调度类型。 首先,重要的是要知道子任务输出类型和调度类型是紧密交织在一起的,只能使两者的特定组合有效。
流水线结果分区是流式输出,需要实时目标子任务才能发送数据。 可以在生成结果之前或首次输出时安排目标。 批处理作业生成有界结果分区,而流式处理作业产生无限结果。
批处理作业也可能以阻塞方式产生结果,具体取决于所使用的运算符和连接模式。 在这种情况下,必须先生成完整的结果,然后才能安排接收任务。 这允许批处理作业更有效地工作并且资源使用更少。
批处理作业也可能以阻塞方式产生结果,具体取决于所使用的运算符和连接模式。 在这种情况下,必须先生成完整的结果,然后才能安排接收任务。 这允许批处理作业更有效地工作并且资源使用更少。
下表总结了有效组合:

1目前Flink未使用。
2批量/流式统一完成后,这可能适用于流式作业。
此外,对于具有多个输入的子任务,调度以两种方式启动:在所有或在任何输入生成器生成记录/其完整数据集之后。 要调整批处理作业中的输出类型和调度决策,请查看ExecutionConfig #setExecutionMode() – 特别是ExecutionMode – 以及ExecutionConfig #setDefaultInputDependencyConstraint()
物理运输
为了理解物理数据连接,请回想一下,在Flink中,不同的任务可以通过插槽共享组共享相同的插槽。 TaskManagers还可以提供多个插槽,以允许将同一任务的多个子任务安排到同一个TaskManager上。
未完待续