以下LocalCluster
的{{1}}配置之间有什么区别?
dask.distributed
与
Client(n_workers=4, processes=False, threads_per_worker=1)
它们都在任务图上有四个线程,但是第一个有四个工作线程。那么,让多个工作人员充当线程而不是一个工作人员具有多个线程有什么好处呢?
编辑:只是为了澄清,我知道进程,线程和共享内存之间的差异,因此,这个问题更多地针对这两个客户端的配置差异。
答案 0 :(得分:1)
当您使用process = False时,就是在限制群集只能通过计算机体系结构工作。
from dask.distributed import Client
# The address provided by processes=False is a In-process transport address.
# This is used to perform communication between threads
# Scheduler and workers are on the same machine.
client = Client(processes=False)
client
<Client: scheduler='inproc://10.0.0.168/31904/1' processes=1 cores=4>
# The address provided on processes=True is tcp protocol.
# This is a network address. You can start workers from others machines
# just pointing the scheduler address to this tcp address
# (All machines must be on the same network).
client = Client(processes=True)
client
<Client: scheduler='tcp://127.0.0.1:53592' processes=4 cores=4>
答案 1 :(得分:1)
您在这里混淆了两件事:
进程数和线程数之间的平衡,不同的混合有利于不同的工作负载。每个工作人员更多的线程意味着更好地共享内存资源并避免了序列化;更少的线程和更多的进程意味着更好地避免了GIL
使用processes=False
,调度程序和工作程序都作为线程在与客户端相同的进程中运行。同样,它们将共享内存资源,您甚至不必在客户端和调度程序之间序列化对象。但是,您将有很多线程,并且客户端的响应速度可能会降低。这通常用于测试,因为可以直接自省调度程序和工作对象。
答案 2 :(得分:0)
我从Victor和Martin的答案中得到了启发,对我进行了更深入的研究,因此,这里是我的理解的深入总结。 (无法在评论中这样做)
首先,请注意,此版本的dask中的调度程序打印输出不是很直观。 processes
实际上是工作线程数,cores
实际上是所有工作线程中线程的总数。
第二,值得一提的是Victor关于TCP地址以及添加/连接更多工作程序的评论。我不确定是否可以通过processes=False
将更多工作线程添加到群集中,但是我认为答案可能是肯定的。
现在,考虑以下脚本:
from dask.distributed import Client
if __name__ == '__main__':
with Client(processes=False) as client: # Config 1
print(client)
with Client(processes=False, n_workers=4) as client: # Config 2
print(client)
with Client(processes=False, n_workers=3) as client: # Config 3
print(client)
with Client(processes=True) as client: # Config 4
print(client)
with Client(processes=True, n_workers=3) as client: # Config 5
print(client)
with Client(processes=True, n_workers=3,
threads_per_worker=1) as client: # Config 6
print(client)
这会为我的笔记本电脑(4核)在dask
2.3.0版中产生以下输出:
<Client: scheduler='inproc://90.147.106.86/14980/1' processes=1 cores=4>
<Client: scheduler='inproc://90.147.106.86/14980/9' processes=4 cores=4>
<Client: scheduler='inproc://90.147.106.86/14980/26' processes=3 cores=6>
<Client: scheduler='tcp://127.0.0.1:51744' processes=4 cores=4>
<Client: scheduler='tcp://127.0.0.1:51788' processes=3 cores=6>
<Client: scheduler='tcp://127.0.0.1:51818' processes=3 cores=3>
这是我对配置之间差异的理解:
dask
调用其函数nprocesses_nthreads()
来设置默认值(使用{{1 }},1个进程和线程数等于可用的内核数。processes=False
,因此线程/工作人员被轻而易举地选择,以使线程总数等于核心数(即1)。同样,打印输出中的n_workers
并不完全正确-实际上是工作程序的数量(在这种情况下,实际上是线程)。 processes
不能平均划分为内核数,因此dask选择2个线程/每个工人过量使用而不是不足。