【发布时间】:2011-06-28 06:59:10
【问题描述】:
我需要一些建议,在 Erlang 中编写一个作业调度程序,它能够在一组工作节点上分配作业(外部操作系统进程)。一项工作可以持续几毫秒到几个小时。 “调度程序”应该是一个全局注册表,作业进入,排序,然后在连接的“工作节点”上分配和执行。工作节点应该能够通过告诉他们能够并行处理多少个作业(插槽)来在调度程序上注册。工作节点应该能够随时加入和离开。
一个例子:
- 调度程序有 10 个作业等待
- 工作节点 A 连接并能够并行处理 3 个作业
- 工作节点 B 连接并能够并行处理 1 个作业
- 一段时间后,另一个工作节点加入,能够并行处理 2 个作业
问题:
我认真地花了一些时间思考这个问题,但我仍然不确定该走哪条路。我目前的解决方案是为调度程序提供一个全局注册的 gen_server ,该调度程序将作业保持在其状态。每个工作节点产生 N 个工作进程并将它们注册到调度程序上。然后,工作进程从调度程序中拉出一个作业(如果当前没有可用的作业,这是一个无限阻塞调用 {noreply, ...})。
这里有一些问题:
- 知道在新工作人员连接时我必须将工作重新分配给另一个工作人员,将每个新工作分配给现有工作人员是否是个好主意? (我认为这就是 Erlang SMP 调度程序的工作方式,但重新分配作业对我来说似乎很头疼)
- 我应该为每个工作程序处理槽启动一个进程吗?这个进程应该在哪里运行:在调度程序节点上还是在工作程序节点上?调度程序应该对工作节点进行 rpc 调用,还是让工作节点拉取新作业然后自己执行它们会更好?
- 最后:这个问题已经解决了吗?在哪里可以找到它的代码? :-) 我已经尝试过使用 RabbitMQ 进行作业调度,但是自定义作业排序和部署增加了很多复杂性。
非常欢迎任何建议!
【问题讨论】:
-
您是否已经考虑过
pool(3)设施?它们可用于动态分配负载和添加节点。请参阅stackoverflow.com/questions/4853750/… 或者它与您正在寻找的完全不同? -
是的,已经考虑过了。但不知道 pool 在这里有什么帮助。如果我对池的理解正确,那么同时进来的 10 万个传入作业将在所有已注册的工作节点上产生 10 万个进程。但是这样我就不能限制并行计算的作业数量,并且添加额外的节点来处理作业负载不会重新平衡作业。
-
这些“工作”要在 Erlang 中实现吗?
-
"job" 在我的例子中是指一个可以持续几毫秒到几个小时的外部操作系统进程。