0

根据官方文档

为 spout/bolt 创建多少个实例。一个任务在同一个 spout/bolt 的零个或多个其他任务的线程上运行。spout/bolt 的任务数量在拓扑的整个生命周期中始终相同,但 spout/bolt 的执行程序(线程)的数量会随时间而变化。这允许拓扑扩展到或多或少的资源,而无需重新部署拓扑或违反 Storm 的约束(例如确保相同值用于相同任务的字段分组)

我的问题是:

  1. 在什么情况下我会选择在一个 executor 中运行多个任务?
  2. 如果我确实在一个 executor 中使用了多个任务,我会在我的 spout 和我的 bolt 之间选择每个 executor 不同数量的任务可能是什么原因(例如每个 bolt executor 2 个任务,但每个 spout executor 只有 1 个任务)?
4

3 回答 3

2
Config#TOPOLOGY_TASKS -> How many tasks to create per component.    

任务执行实际的数据处理,并在其父执行程序的执行线程中运行。您在代码中实现的每个 spout 或 bolt 都会在集群中执行尽可能多的任务。

在拓扑的整个生命周期中,组件的任务数量始终相同,但组件的执行器(线程)数量会随时间而变化。这意味着以下条件成立:#threads <= #tasks

默认情况下,任务数设置为与执行程序数相同,即 Storm 将每个线程运行一个任务(这通常是您想要的)。

另请注意:

  • 启动拓扑后可以更改执行器线程的数量。

  • 拓扑的任务数量是静态的。

于 2017-12-08T12:28:57.953 回答
2

我认为https://stackoverflow.com/a/47714449/8845188是一个很好的答案,但我会尝试将其改写为示例:

提交拓扑时,组件(例如 spout 或 bolt)的任务数量是一成不变的,而执行器的数量可以在不重新部署拓扑的情况下更改。执行者的数量总是小于或等于一个组件的任务数量。

问题 1

您通常没有理由选择在 1 个执行器中运行例如 2 个任务,但如果您当前的负载较低但预计稍后会出现高负载,您可以选择提交任务数量多但数量少的拓扑的执行者。当然,您可以根据需要提交具有尽可能多的执行程序的拓扑,但是由于上下文切换和/或潜在的资源争用,当您只需要几个线程时使用多个线程效率低下。

例如,假设您提交了拓扑,因此 spout 有 4 个任务和 4 个执行器(每个执行器一个)。当您的负载增加时,您无法进一步扩展,因为 4 是您可以拥有的最大执行器数量。您现在必须重新部署拓扑以随负载扩展。

假设您提交了拓扑,因此 spout 有 32 个任务和 4 个执行器(每个 8 个)。当负载增加时,您可以将执行程序的数量增加到 32 个,即使您一开始只有 4 个。您可以在不重新部署拓扑的情况下进行扩展。

问题2

假设您的拓扑有一个 spout A 和一个 bolt B。假设 bolt B 做了一些重量级的工作(例如,每个执行器每秒可以做 10 个元组),而 spout 是轻量级的(例如,每个执行器每秒可以做 1000 个元组) . 假设您的负载最初是每秒 20 条消息进入拓扑,但您希望它会增长。

在这种情况下,您可以使用 1 个执行程序和 1 个任务来配置您的 spout,因为它可能大部分时间都处于空闲状态。同时,您希望为 Bolt 配置大量任务,以便为它扩展执行器的数量,并至少启动 2-3 个执行器。

于 2017-12-30T19:38:49.320 回答
0

还有另一个原因是让任务代替执行者更有意义。假设您在单个执行程序(线程)上运行相同螺栓的 2 个任务。假设您正在调用一个运行时间相对较长(可能需要 1 秒)的数据库子例程,并且在继续之前需要结果。

案例 1 - 您的数据库调用将在执行程序线程上运行,它会暂停一段时间,并且您不会通过运行 2 个任务获得任何收益。案例 2 - 您重构数据库调用代码以生成新线程并执行。在这种情况下,您的主执行器线程不会挂起,它将能够开始处理第二个螺栓任务,而新生成的线程将从数据库中获取数据。

除非您在组件中引入自己的并行性,否则除了其他答案中提到的维护原因之外,我看不到性能提升并且没有理由运行多个任务。

于 2018-01-08T06:26:31.623 回答