我受到Victor和Martin的回答的启发,想深入了解一下,因此这里是我理解的深度总结。(无法在评论中完成)
首先,请注意此版本dask中的调度程序输出并不直观。processes
实际上是工作进程(worker)的数量,cores
实际上是所有worker中线程(thread)的总数。
其次,Victor关于TCP地址以及添加/连接更多worker的评论是值得指出的。我不确定是否可以在 processes=False
的情况下向集群添加更多worker,但我认为答案可能是“是”。
现在,请考虑以下脚本:
from dask.distributed import Client
if __name__ == '__main__':
with Client(processes=False) as client:
print(client)
with Client(processes=False, n_workers=4) as client:
print(client)
with Client(processes=False, n_workers=3) as client:
print(client)
with Client(processes=True) as client:
print(client)
with Client(processes=True, n_workers=3) as client:
print(client)
with Client(processes=True, n_workers=3,
threads_per_worker=1) as client:
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>
以下是我对配置差异的理解:
- 调度程序和所有工作程序都作为客户端进程中的线程运行。(如Martin所说,这对于内省很有用。)由于未给出工作程序或每个工作程序线程的数量,因此
dask
调用其函数 nprocesses_nthreads()
来设置默认值(在 processes=False
的情况下,1 个进程和线程等于可用核心数)。
- 与第一种相同,但由于给定了
n_workers
,因此 dask 选择线程/工作程序,使得总线程数等于核心数(即为 1)。同样,在打印输出中的 processes
不是完全正确 - 实际上,它是工作程序的数量(在这种情况下实际上是线程)。
- 与第二种相同,但由于
n_workers
不能被核心数整除,dask 选择 2 个线程/工作程序进行过量提交而不是欠量提交。
- 客户端、调度程序和所有工作程序都是单独的进程。Dask 选择默认数量的工作程序(等于核心数,因为它小于等于 4)和每个工作程序的默认线程数(1)。
- 与第 5 种相同的进程/线程配置,但由于与第 3 种相同的原因,总线程数被过量预约。
- 这个行为符合预期。
n_workers
的客户端,为什么会这样?这如何符合“进程”实际上是工作人员数量的概念,为什么不限于我的机器上的物理核心数? - Luis Chaves Rodriguez