Storm:什么时候使用 setNumTasks?

Storm: when to use setNumTasks?

我很好奇需要使用 setNumTasks 函数的情况。文档说默认是每个执行者一个任务。

如果我有一个 'expensive' 数据库任务(调用需要时间的外部数据库)到 运行 与 'fast' 任一侧的任务,我应该添加为此需要额外的任务吗?

或者这是 'try it and see what happens' 种情况之一?

  • 任务数总是>=执行者数
    • 可以更改执行程序的数量(不会破坏拓扑),但必须遵守约束 num tasks >= num executors。也就是说,如果你的任务比执行者多,你可以重新平衡你的拓扑并给它更多的执行者。

如何决定你需要多少 executors/tasks?

  • 寻找瓶颈,你指出的是一个很好的瓶颈,访问外部数据源的延迟(查看 storm UI 上的 bolt 进程延迟)。在这种情况下,你可以(可能应该)在这个螺栓上有更多的执行单元;如果您有 "spare" 个任务,您可以将它们提升为执行者。
  • 另一个瓶颈是 CPU 用法(查看 storm 上的螺栓容量 UI),更加 CPU 密集的螺栓将需要更多的执行单元。

我推荐你阅读this page

我刚刚验证了这一点,发现了为什么任务会出现这种混乱。

在这种情况下:

int BoltParallelism = 3;
int BoltTaskParallelism = 2;
builder.setBolt("bolt1", new BoltA(), BoltParallelism)
                .setNumTasks(BoltTaskParallelism)

BoltParallelism确实是执行者的数量,BoltTaskParallelism确实是任务的数量。

但是

int BoltParallelism = 3;
builder.setBolt("bolt1", new BoltA(), BoltParallelism)

当您不指定 setNumTasks 时,Storm 会创建 BoltParallelism 个任务并创建 BoltParallelism 个执行程序。

如果您创建了 3 个任务,那么 Storm 会创建 3 个 Bolt A 实例。如果您的昂贵的数据库读取发生在 BoltA 的一个实例中,那么很可能 BoltA 的其他实例也会做同样的事情,因为它是相同的 class。但是,如果您以 BoltA class 可能在某些条件下执行数据库读取而在其他条件下执行其他处理的方式编写逻辑,那么可以;有更多的任务是值得的,并且每个任务 运行 在不同的执行者(线程)中是值得的,因为如果你有 3 个任务而只有一个执行者,那么任务将是 运行 一个接一个由执行人。