我正在寻找一个python包,它不仅可以跨单个计算机中的不同内核进行多处理,还可以跨多个计算机分布。分布式计算有许多不同的python包,但大多数似乎需要更改代码才能运行(例如,前缀表明对象在远程计算机上)。具体来说,我希望尽可能接近多处理pool.map
函数。因此,例如,如果在一台机器上脚本是:
from multiprocessing import Pool
pool = Pool(processes = 8)
resultlist = pool.map(function, arglist)
然后,分布式集群的伪代码将是:
from distprocess import Connect, Pool, Cluster
pool1 = Pool(processes = 8)
c = Connect(ipaddress)
pool2 = c.Pool(processes = 4)
cluster = Cluster([pool1, pool2])
resultlist = cluster.map(function, arglist)
答案 0 :(得分:10)
如果你想要一个非常简单的解决方案,那就没有了。
但是,有一个解决方案具有multiprocessing
接口 - pathos
- 它能够通过并行映射建立与远程服务器的连接,并进行多处理。
如果你想拥有一个ssh-tunneled连接,你可以这样做......或者你可以使用安全性较低的方法,你也可以这样做。
>>> # establish a ssh tunnel
>>> from pathos.core import connect
>>> tunnel = connect('remote.computer.com', port=1234)
>>> tunnel
Tunnel('-q -N -L55774:remote.computer.com:1234 remote.computer.com')
>>> tunnel._lport
55774
>>> tunnel._rport
1234
>>>
>>> # define some function to run in parallel
>>> def sleepy_squared(x):
... from time import sleep
... sleep(1.0)
... return x**2
...
>>> # build a pool of servers and execute the parallel map
>>> from pathos.pp import ParallelPythonPool as Pool
>>> p = Pool(8, servers=('localhost:55774',))
>>> p.servers
('localhost:55774',)
>>> y = p.map(sleepy_squared, x)
>>> y
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
或者,您可以配置直接连接(无ssh)
>>> p = Pool(8, servers=('remote.computer.com:5678',))
# use an asynchronous parallel map
>>> res = p.amap(sleepy_squared, x)
>>> res.get()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
它有点挑剔,要使远程服务器正常工作,您必须事先启动在指定端口remote.computer.com
上运行的服务器 - 并且您必须确保这两个设置在您的localhost和远程主机上将允许直接连接或ssh-tunneled连接。此外,您需要在每台主机上运行相同版本的pathos
和pathos
pp
分叉。此外,对于ssh,您需要运行ssh-agent以允许使用ssh进行无密码登录。
但是,希望它一切正常......如果您的功能代码可以通过dill.source.importable
传输到远程主机。
仅供参考,pathos
早就应该发布,基本上,在新的稳定版本被删除之前,需要解决一些错误和界面更改。
答案 1 :(得分:9)
我建议您查看Ray,其目的就是做到这一点。
Ray使用相同的语法来并行化单机多核设置中的代码,就像在分布式设置中一样。如果您愿意使用for循环而不是地图调用,那么您的示例将如下所示。
import ray
import time
ray.init()
@ray.remote
def function(x):
time.sleep(0.1)
return x
arglist = [1, 2, 3, 4]
result_ids = [function.remote(x) for x in arglist]
resultlist = ray.get(result_ids)
这将使用您在本地拥有的多个核心并行运行四个任务。要在群集上运行相同的示例,唯一可以更改的行是对ray.init()
的调用。可以找到相关文档here。
请注意,我正在帮助开发Ray。
答案 2 :(得分:8)
这里的派对有点晚了,但由于我也在寻找类似的解决方案,而且这个问题仍然没有得到回答,我想我会贡献我的发现。
我最终使用SCOOP。它提供了一个并行映射实现,可以跨多个主机跨多个内核工作。如果需要,它还可以在调用期间回退到Python的串行map
函数。
在SCOOP的介绍页面中,它引用了以下功能:
SCOOP的特点和优势超过期货,多处理和 类似的模块如下:
- 通过网络利用多台计算机的强大功能;
- 能够在任务中生成多个任务;
- API与PEP-3148;
兼容- 只需稍加修改即可并行化串行代码;
- 高效的负载平衡。
它确实有一些怪癖(函数/类必须是可选择的),并且如果它们不共享相同的文件系统架构,那么在多个主机上顺利运行的设置可能会很乏味,但总的来说我是&#39 ;我对结果非常满意。为了我们的目的,做了相当多的Numpy& Cython,它提供了出色的性能。
希望这会有所帮助。
答案 3 :(得分:0)
你看过disco吗?
特点:
迪斯科文档中的一个简单示例:
from disco.core import Job, result_iterator
def map(line, params):
for word in line.split():
yield word, 1
def reduce(iter, params):
from disco.util import kvgroup
for word, counts in kvgroup(sorted(iter)):
yield word, sum(counts)
if __name__ == '__main__':
job = Job().run(input=["http://discoproject.org/media/text/chekhov.txt"],
map=map,
reduce=reduce)
for word, count in result_iterator(job.wait(show=True)):
print(word, count)