编写一个并行编程框架,我错过了什么?

16
澄清:根据一些评论,我应该澄清这是一个简单的框架,旨在允许执行本质上是并行的程序(所谓的尴尬的并行程序)。它不是,也永远不会成为需要进程间通信或同步的任务的解决方案。
我一直在寻找一个简单的基于进程的Python并行编程环境,可以在集群上的多个CPU上执行函数,主要标准是需要能够执行未修改的Python代码。我找到的最接近的是Parallel Python,但pp做了一些相当奇怪的事情,可能导致代码未在正确的上下文中执行(导入了适当的模块等)。
最后,我厌倦了搜索,所以决定写自己的。我想出的实际上非常简单。问题是,我不确定我想出的东西是否简单,因为我可能没有考虑到很多事情。这是我的程序做的事情:
  • I have a job server which hands out jobs to nodes in the cluster.
  • The jobs are handed out to servers listening on nodes by passing a dictionary that looks like this:

    {
    'moduleName':'some_module', 
    'funcName':'someFunction', 
    'localVars': {'someVar':someVal,...}, 
    'globalVars':{'someOtherVar':someOtherVal,...}, 
    'modulePath':'/a/path/to/a/directory', 
    'customPathHasPriority':aBoolean, 
    'args':(arg1,arg2,...), 
    'kwargs':{'kw1':val1, 'kw2':val2,...}
    }
    
  • moduleName and funcName are mandatory, and the others are optional.

  • A node server takes this dictionary and does:

    sys.path.append(modulePath)
    globals()[moduleName]=__import__(moduleName, localVars, globalVars)
    returnVal = globals()[moduleName].__dict__[funcName](*args, **kwargs)
    
  • On getting the return value, the server then sends it back to the job server which puts it into a thread-safe queue.

  • When the last job returns, the job server writes the output to a file and quits.
我确定还有需要解决的问题,但是这种方法有什么明显的错误吗?第一眼看上去,它似乎很强大,只需要节点可以访问包含.py文件和依赖项的文件系统。使用__import__的优点在于模块中的代码会自动运行,因此函数应该在正确的上下文中执行。
如有建议或批评,将不胜感激。
编辑:我应该提到,我已经让代码执行了,但服务器和作业服务器还没有编写。

1
这是非常雄心勃勃的。你能把它转化成一个问题吗? - Rafe Kettler
1
@katriealex:不,pp绝对不能做我想要的事情。我花了几周时间试图将我的程序塞进pp的范式中,但一直遇到一个又一个的错误。pp有一些非常奇怪的问题。例如,由于没有明显的原因,在numpy库的深处会出现几个import语句失败。我认为问题在于pp尝试在“干净”的环境中执行函数,并期望您明确指定代码所依赖的所有模块、需要调用的设置代码等。使用pp编写简单的程序很容易,但编写复杂的程序则很困难。 - Chinmay Kanchi
1
我不确定应该放在什么地方,但你能否详细解释一下为什么pp不能满足你的需求呢?我对你的评论感到困惑。是pp的工作方式与你的期望不同,还是它没有如广告所述那样工作?我现在正在研究一些pp代码,很想了解它存在的问题以及它的工作原理。编辑:我知道正确的地方在哪里了,另一个问题!我现在就提出来。 - Thomas
编写任何编程语言中的非平凡并行程序,更不用说表现良好的程序,都是很困难的。你确定问题是框架,而不是你正在尝试完成的任务吗? - Ira Baxter
1
如果有许多集群节点,作业服务器(在您的方法和jug中)可能会成为瓶颈。 - Sven Marnach
显示剩余10条评论
2个回答

8
我已经写了一些东西,可能满足您的需求:jug。如果它不能解决您的问题,我保证会修复您发现的任何错误。
这个架构略有不同:工作者们都运行相同的代码,但他们实际上生成一个类似的字典并询问中央后端“是否已经运行过”?如果没有,他们就运行它(还有锁定机制)。如果您使用的是NFS系统,则后端可以简单地是文件系统。

这看起来非常有趣。我会仔细看一下并告诉你进展如何! - Chinmay Kanchi
不幸的是,由于jug控制工作程序的启动,它对我来说并不是一个好的解决方案。我主要使用的集群使用Sun GridEngine来调度作业,我不能允许进程在SGE调度器之外被生成。 - Chinmay Kanchi
2
它应该是可以正常工作的。您只需使用SGE调度程序启动“jug execute”作业(这实际上是我个人使用的设置!)。即使作业在不同时间开始,它也可以正常工作。 - luispedro
好的,我可能误解了文档。我真的没有时间给它应有的关注,一直在忙其他的事情... - Chinmay Kanchi
很抱歉这个奖励问题,但我认为如果没有更好的答案,它应该会给你的。这以前一直是这样的。不管怎样我还是会接受你的答案... - Chinmay Kanchi

5

我自己一直在研究跨计算机的批量图像处理,最大的问题是有些东西不容易或本地无法pickle和跨网络传输。

例如:pygame的surfaces不能pickle。这些我必须通过将它们保存在StringIO对象中并将其转储到网络上来将它们转换为字符串。

如果您要传输的数据(例如您的参数)可以安全传输,那么您在网络数据方面就不应该有太多问题。

还有一件事:如果在执行任务时计算机突然“消失”了怎么办?在返回数据时呢?您有重新发送任务的计划吗?


是的,我一直在考虑每隔“x”秒轮询每个节点,如果一个节点连续“y”次未响应,则将作业发送到第一个完成的节点,或者在不同的节点上生成新的服务器进程(用户将指定采取哪种替代方案)。我还需要一种明智的方式来处理节点上发生的错误和/或异常。 - Chinmay Kanchi
如何处理“不可反序列化”的参数是一个很好的问题,我怀疑它没有一个通用的答案。编写一个基本处理程序来简单地反序列化参数可能是一个好主意,但允许它被子类化以处理特殊情况。 - Chinmay Kanchi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接