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