我已经探索了几天的Apache Flink,我对任务槽的概念有些怀疑。虽然已经问了几个问题,但有一点我不明白。
我正在使用玩具应用程序进行测试,运行本地集群。我已禁用运算符链接
我从文档中知道插槽允许内存隔离而不是 CPU 隔离。阅读文档,似乎任务槽是一个 Java 线程。
1) 当我以并行度 = 1 部署应用程序时,所有操作员的子任务都部署在同一插槽中。但是,如果我从AbstractStreamOperator
的open()
方法打印当前线程 ID,我看到不同的子任务有不同的 ID。那么,它们不是共享同一个线程(即插槽?
2) 如果我将并行度从 1 更改为 3,我需要 3 个插槽才能正确重新部署应用程序。文档证实插槽的数量限制了我可以拥有的并行性。但是为什么我可以在同一插槽中拥有不同操作员的子任务,而在同一插槽中却不能具有同一操作员的子任务?
感谢您的任何解释!
插槽的想法是将可用资源切成更小的部分。可用的托管内存在所有插槽之间均匀分布。CPU 周期和 JVM 堆内存不是正确隔离的 wrt 插槽。
在每个插槽中,您可以部署一个或多个Tasks
。FlinkTask
由专用线程执行。因此,如果部署了多个Tasks
,则可以在同一槽中运行多个线程。
Task
表示单个 Flink 运算符或多个运算符(如果它们是可链接的)的并行实例。链接并不总是可能的或需要的,但如果应用它将融合运算符,以便它们由同一Task
线程执行。这通常更有效,因为上下文切换较少,并且没有将记录移交给不同的线程。
为了提高资源利用率(特别是对于需要很少资源的Tasks
),并使运行 Flink 程序需要多少插槽的推理更容易,Flink 支持插槽共享。槽位共享意味着可以将不同算子的并行实例部署到同一个槽位。由于这个特性,Flink 会创建尽可能长的不同算子的流水线,并将它们部署到同一个槽位。这也是一个很好的效果,即您可以增加生产者与其各自消费者的共置位置。由于此功能,用户知道他们只需要提供与拓扑的所有运算符的最大并行度一样多的插槽。
但是,由于您仍然希望将一个算子的并行实例分布到所有可用的TaskExecutors
,Flink 不支持将同一算子的并行实例部署到同一槽中。如果要执行此操作,则只需将相应运算符的并行度降低到1
即可。