1. 错开策略(Staggering Policy)

WindowStagger 在运行时为每个窗口分配错开偏移量:


2. 并行度(Parallelism)

2.1. 任务和算子链

对于分布式执行,Flink 将算子子任务链接到任务中。每个任务由一个线程执行。将算子链接到任务中是一种有用的优化:它减少线程间切换和缓冲的开销,并且在减少延迟的同时,提高总体吞吐量。链接行为可配置,请查看 chaining docs 获取细节。

下图中的示例数据流由 5 个子任务执行,因此有 5 个并行线程。

2.2. 并行度

算子的子任务(Subtask)个数被称之为其并行度(Parallelism)。一般情况下,流程序的并行度可以认为是其所有算子中最大的并行度。一个程序中,不同的算子可能具有不同的并行度。

2.3. 设置并行度

2.3.1. 算子级别(Operator Level)并行度

可以通过调用 setParallelism() 方法,指定算子、数据源和数据汇的并行度。

2.3.2. Env 级别(Execution Environment Level)并行度

可以通过调用 setParallelism() 方法,指定执行环境的默认并行度。执行环境的并行度可以通过显式设置算子的并行度而被重写。

2.3.3. 客户端级别(Client Level)并行度

可以在客户端将任务提交到 Flink 时设定。

2.3.4. 系统默认级别(System Level)并行度

可以通过设置 flink-conf.yaml 文件中的 parallelism.default 属性,指定所有执行环境的默认并行度。

2.3.5. 优先级

算子级别 > Env 级别 > 客户端级别 > 系统默认级别


3. 任务槽(Task Slot)和资源

每个 Worker(TaskManager)是一个 JVM 进程,可以在单独的线程中执行一或多个子任务。为控制 TaskManager 接受多少任务,它有所谓的任务槽(至少一个)。

每个任务槽代表 TaskManager 资源的固定子集。比如拥有 3 个槽的 TaskManager 将为每个槽分配 1/3 的托管内存。槽化资源意味着子任务不会与其它作业的子任务竞争托管内存,而是拥有特定数量的预留托管内存。注意,这里没有发生 CPU 隔离;目前,槽仅分隔任务的托管内存。

通过调整任务槽的数量,用户可以定义子任务彼此隔离的方式。每个 TaskManager 有 1 个插槽意味着每个任务组在单独的 JVM 中运行(比如,可以在单独的容器中启动)。拥有多个插槽意味着更多的子任务共享同一个 JVM。同一 JVM 中的任务共享 TCP 连接(通过多路复用)和心跳消息。它们还可以共享数据集和数据结构,从而减少每个任务的开销。

默认情况下,Flink 允许子任务共享槽,即便它们是不同任务的子任务,只要它们来自于相同的作业。结果是一个槽可能持有作业的整个管道。允许槽共享有两个好处:


参考文档