Apache 风暴:为什么以及如何选择每个执行者的任务数?
Apache storm: why and how to choose number of tasks per executor?
How many instances to create for a spout/bolt. A task runs on a thread with zero or more other tasks for the same spout/bolt. The number of tasks for a spout/bolt is always the same throughout the lifetime of a topology, but the number of executors (threads) for a spout/bolt can change over time. This allows a topology to scale to more or less resources without redeploying the topology or violating the constraints of Storm (such as a fields grouping guaranteeing that the same value goes to the same task)
我的问题是:
- 在什么情况下我会选择运行一个执行器中的多个任务?
- 如果我确实在一个执行器中使用多个任务,可能是什么原因导致我会在 spout 和 bolt 之间为每个执行器选择不同数量的任务(例如每个 bolt 执行器有 2 个任务,但每个 spout 执行器只有 1 个任务)?
Config#TOPOLOGY_TASKS -> How many tasks to create per component.
任务执行实际的数据处理,并且在其父执行程序的执行线程中 运行。您在代码中实现的每个 spout 或 bolt 都会在集群中执行尽可能多的任务。
组件的任务数在拓扑的整个生命周期中始终相同,但组件的执行器(线程)数量会随时间变化。这意味着以下条件成立:#threads <= #tasks
。
默认情况下,任务的数量设置为与执行者的数量相同,即 Storm 将 运行 每个线程一个任务(这通常是你想要的)。
另请注意:
拓扑启动后可以更改执行线程数。
拓扑的任务数是静态的
我认为 是一个很好的答案,但我会尝试改写它作为示例:
当您提交拓扑时,一个组件(例如 spout 或 bolt)的任务数量是一成不变的,而执行者的数量可以在不重新部署拓扑的情况下更改。 executors 的数量总是小于或等于组件的 tasks 数量。
问题 1
您通常没有理由选择 运行 例如1 个执行器中有 2 个任务,但是如果您当前的负载较低但预计稍后会出现高负载,则您可以选择提交具有大量任务但执行器数量较少的拓扑。您当然可以只提交包含您期望的尽可能多的执行程序的拓扑,但是当您只需要几个线程时使用多个线程是低效的,因为上下文切换 and/or 潜在的资源争用。
例如,假设您提交了拓扑,因此 spout 有 4 个任务和 4 个执行程序(每个执行程序一个)。当您的负载增加时,您无法进一步扩展,因为 4 是您可以拥有的最大执行程序数。您现在必须重新部署拓扑才能随负载扩展。
假设您提交了拓扑,因此 spout 有 32 个任务和 4 个执行程序(每个 8 个)。当负载增加时,您可以将执行程序的数量增加到 32,即使您开始时只有 4 个。您可以在不重新部署拓扑的情况下进行扩展。
问题 2
假设您的拓扑有一个 spout A 和一个 bolt B。假设 bolt B 做一些重量级的工作(例如每个执行者每秒可以做 10 个元组),而 spout 是轻量级的(例如可以做 1000 个元组)每个执行者每秒)。假设您的负载最初是每秒 20 条消息进入拓扑,但您希望它增长。
在这种情况下,您可以为 spout 配置 1 个执行程序和 1 个任务是有意义的,因为它可能大部分时间都处于空闲状态。同时你想为你的 bolt 配置大量的任务,这样你就可以为它扩展执行器的数量,并且至少要启动 2-3 个执行器。
还有一个原因是用任务代替执行者更有意义。
假设您在单个执行程序(线程)上有 2 个相同螺栓 运行ning 的任务。假设您正在调用一个相对较长的 运行ning(可能 1 秒)数据库子例程,并且在继续进行之前需要结果。
案例 1 - 您的数据库调用将在执行程序线程上 运行ning 并且它会暂停一段时间并且您不会通过 运行ning 2 个任务获得任何东西。
案例 2 - 您重构数据库调用代码以生成新线程并执行。在这种情况下,您的主执行程序线程不会挂起,它可以开始处理第二个 bolt 任务,而新生成的线程将从数据库中获取数据。
除非您在组件中引入自己的并行性,否则我看不到性能提升,也没有理由 运行 除了维护原因之外的多个任务,如其他答案中所述。
How many instances to create for a spout/bolt. A task runs on a thread with zero or more other tasks for the same spout/bolt. The number of tasks for a spout/bolt is always the same throughout the lifetime of a topology, but the number of executors (threads) for a spout/bolt can change over time. This allows a topology to scale to more or less resources without redeploying the topology or violating the constraints of Storm (such as a fields grouping guaranteeing that the same value goes to the same task)
我的问题是:
- 在什么情况下我会选择运行一个执行器中的多个任务?
- 如果我确实在一个执行器中使用多个任务,可能是什么原因导致我会在 spout 和 bolt 之间为每个执行器选择不同数量的任务(例如每个 bolt 执行器有 2 个任务,但每个 spout 执行器只有 1 个任务)?
Config#TOPOLOGY_TASKS -> How many tasks to create per component.
任务执行实际的数据处理,并且在其父执行程序的执行线程中 运行。您在代码中实现的每个 spout 或 bolt 都会在集群中执行尽可能多的任务。
组件的任务数在拓扑的整个生命周期中始终相同,但组件的执行器(线程)数量会随时间变化。这意味着以下条件成立:#threads <= #tasks
。
默认情况下,任务的数量设置为与执行者的数量相同,即 Storm 将 运行 每个线程一个任务(这通常是你想要的)。
另请注意:
拓扑启动后可以更改执行线程数。
拓扑的任务数是静态的
我认为
当您提交拓扑时,一个组件(例如 spout 或 bolt)的任务数量是一成不变的,而执行者的数量可以在不重新部署拓扑的情况下更改。 executors 的数量总是小于或等于组件的 tasks 数量。
问题 1
您通常没有理由选择 运行 例如1 个执行器中有 2 个任务,但是如果您当前的负载较低但预计稍后会出现高负载,则您可以选择提交具有大量任务但执行器数量较少的拓扑。您当然可以只提交包含您期望的尽可能多的执行程序的拓扑,但是当您只需要几个线程时使用多个线程是低效的,因为上下文切换 and/or 潜在的资源争用。
例如,假设您提交了拓扑,因此 spout 有 4 个任务和 4 个执行程序(每个执行程序一个)。当您的负载增加时,您无法进一步扩展,因为 4 是您可以拥有的最大执行程序数。您现在必须重新部署拓扑才能随负载扩展。
假设您提交了拓扑,因此 spout 有 32 个任务和 4 个执行程序(每个 8 个)。当负载增加时,您可以将执行程序的数量增加到 32,即使您开始时只有 4 个。您可以在不重新部署拓扑的情况下进行扩展。
问题 2
假设您的拓扑有一个 spout A 和一个 bolt B。假设 bolt B 做一些重量级的工作(例如每个执行者每秒可以做 10 个元组),而 spout 是轻量级的(例如可以做 1000 个元组)每个执行者每秒)。假设您的负载最初是每秒 20 条消息进入拓扑,但您希望它增长。
在这种情况下,您可以为 spout 配置 1 个执行程序和 1 个任务是有意义的,因为它可能大部分时间都处于空闲状态。同时你想为你的 bolt 配置大量的任务,这样你就可以为它扩展执行器的数量,并且至少要启动 2-3 个执行器。
还有一个原因是用任务代替执行者更有意义。 假设您在单个执行程序(线程)上有 2 个相同螺栓 运行ning 的任务。假设您正在调用一个相对较长的 运行ning(可能 1 秒)数据库子例程,并且在继续进行之前需要结果。
案例 1 - 您的数据库调用将在执行程序线程上 运行ning 并且它会暂停一段时间并且您不会通过 运行ning 2 个任务获得任何东西。 案例 2 - 您重构数据库调用代码以生成新线程并执行。在这种情况下,您的主执行程序线程不会挂起,它可以开始处理第二个 bolt 任务,而新生成的线程将从数据库中获取数据。
除非您在组件中引入自己的并行性,否则我看不到性能提升,也没有理由 运行 除了维护原因之外的多个任务,如其他答案中所述。