Python 如何在不使用所有工作人员的情况下限制大量任务
假设我有一个dask网格,共有10个工人和40个核心。这是一个共享的网格,所以我不想让我的工作完全浸透它。我有1000个任务要做,我想一次最多提交(并积极运行)20个任务 具体来说,Python 如何在不使用所有工作人员的情况下限制大量任务,python,dask,Python,Dask,假设我有一个dask网格,共有10个工人和40个核心。这是一个共享的网格,所以我不想让我的工作完全浸透它。我有1000个任务要做,我想一次最多提交(并积极运行)20个任务 具体来说, from time import sleep from random import random def inc(x): from random import random sleep(random() * 2) return x + 1 def double(x): from
from time import sleep
from random import random
def inc(x):
from random import random
sleep(random() * 2)
return x + 1
def double(x):
from random import random
sleep(random())
return 2 * x
>>> from distributed import Executor
>>> e = Executor('127.0.0.1:8786')
>>> e
<Executor: scheduler=127.0.0.1:8786 workers=10 threads=40>
这会起作用,但是,这只会将我所有的任务转储到网格中,使其饱和。理想情况下,我可以:
e.scatter(input_q, max_submit=20)
文档中的示例似乎允许我使用maxsize
队列。但从用户的角度来看,我仍然需要处理背压。理想情况下,dask
会自动处理这个问题 使用maxsize=
你很接近。所有scatter
、collect
和map
都采用与Queue
相同的maxsize=
关键字参数。因此,一个简单的工作流可能如下所示:
例子
所有q
、futures
和results
都是Python队列对象。q
和results
队列没有限制,因此它们会贪婪地尽可能多地加入。然而,futures
队列的最大大小为20,因此它在任何给定时间只允许20个futures在飞行中。一旦前导期货完成,它将立即被gather函数使用,其结果将被放入结果
队列。这会释放futures
中的空间,并导致提交另一个任务
请注意,这并不是您想要的。这些队列是有序的,因此只有当它们位于队列前面时,才会弹出未来。如果所有的飞行中的期货都完成了,除了第一个,它们仍然会留在队列中,占据空间。考虑到这一限制,您可能希望选择比所需的20
项稍多的maxsize=
扩展这个
这里我们做一个简单的
map->gather
管道,中间没有逻辑。您还可以将其他map
计算放在这里,甚至可以将期货从队列中取出,自己使用它们进行自定义工作。很容易打破上面提供的模式。发布在github上的解决方案非常有用-
解决方案:
inputs = iter(inputs)
futures = [c.submit(func, next(inputs)) for i in range(maxsize)]
ac = as_completed(futures)
for finished_future in ac:
# submit new future
try:
new_future = c.submit(func, next(inputs))
ac.append(new_future)
except StopIteration:
pass
result = finished_future.result()
... # do stuff with result
查询:
inputs = iter(inputs)
futures = [c.submit(func, next(inputs)) for i in range(maxsize)]
ac = as_completed(futures)
for finished_future in ac:
# submit new future
try:
new_future = c.submit(func, next(inputs))
ac.append(new_future)
except StopIteration:
pass
result = finished_future.result()
... # do stuff with result
但是,为了确定可以自由限制任务的工作者,我尝试利用client.has_what()api。工作人员的负载似乎不会立即得到反映,与状态UI页面上显示的内容类似。有时,需要花费相当多的时间来确定要反映哪些数据
是否有其他api可用于确定自由工作人员的数量,然后可用于确定节流范围,类似于用户界面所使用的范围。最好将解决方案代码复制/粘贴到答案中。我假设它是由mrocklin在那个问题线程中提供的答案。为人们寻找解决方案节省了时间,并使答案更加完整。@Lex-感谢您指出这一点,上面添加了解决方案。这是一个答案还是一个问题?这对我来说很好,但在最新版本的dask
ac.append
中变成了ac.add
。还有一个ac.update
,如果您需要的话,它允许您添加多个期货。
inputs = iter(inputs)
futures = [c.submit(func, next(inputs)) for i in range(maxsize)]
ac = as_completed(futures)
for finished_future in ac:
# submit new future
try:
new_future = c.submit(func, next(inputs))
ac.append(new_future)
except StopIteration:
pass
result = finished_future.result()
... # do stuff with result