如何在不使用所有工作程序的情况下限制大量任务

时间:2016-08-12 15:28:42

标签: python dask

想象一下,我有一个拥有10名工人的dask网格&共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 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>

如果我设置了队列系统

>>> from queue import Queue
>>> input_q = Queue()
>>> remote_q = e.scatter(input_q)
>>> inc_q = e.map(inc, remote_q)
>>> double_q = e.map(double, inc_q)

这将有效,但是,这只会将我的所有任务转储到网格中,使其饱和。理想情况下我可以:

e.scatter(input_q, max_submit=20)

似乎来自文档here的示例允许我使用maxsize队列。但从用户的角度来看,我仍然需要处理背压。理想情况下dask会自动处理此问题。

2 个答案:

答案 0 :(得分:6)

使用maxsize=

你非常接近。 scattergathermap的所有内容都采用与maxsize=相同的Queue关键字参数。因此,简单的工作流程可能如下:

实施例

from time import sleep

def inc(x):
    sleep(1)
    return x + 1

your_input_data = list(range(1000))

from queue import Queue              # Put your data into a queue
q = Queue()
for i in your_input_data:
    q.put(i)

from dask.distributed import Executor
e = Executor('127.0.0.1:8786')        # Connect to cluster


futures = e.map(inc, q, maxsize=20)  # Map inc over data
results = e.gather(futures)          # Gather results

L = []
while not q.empty() or not futures.empty() or not results.empty():
    L.append(results.get())  # this blocks waiting for all results

所有qfuturesresults都是Python Queue对象。 qresults队列没有限制,因此他们会尽可能地贪婪地吸引他们。但futures队列的最大大小为20,因此在任何给定时间它只允许20个期货在飞行中。一旦领先的未来完成,它将立即被收集功能使用,其结果将被放入results队列。这释放了futures中的空间,并导致另一个任务被提交。

请注意,这并不是您想要的。这些队列是按顺序排列的,因此只有当它们位于队列前面时,它才会被弹出。如果所有的飞行中的期货都已完成,除了第一个它们仍然留在队列中,占用空间。根据此约束条件,您可能希望选择maxsize=略高于所需20项的内容。

扩展此

这里我们做一个简单的map->gather管道,其间没有逻辑。您还可以将其他map计算放在此处,甚至将期货从队列中拉出来,并自行定制。它很容易脱离上面提供的模具。

答案 1 :(得分:1)

在github上发布的解决方案非常有用 - https://github.com/dask/distributed/issues/864

<强>解决方案:

wb = load_workbook(filename = 'testing.xlsx')

sheet_name = 'AR Cutoff'

# index of [sheet_name] sheet
idx = wb.sheetnames.index(sheet_name)

# remove [sheet_name]
wb.remove(writer.book.worksheets[idx])

# create an empty sheet [sheet_name] using old index
wb.create_sheet(sheet_name, idx)

<强>查询:

但是,为了确定可以自由限制任务的工作人员,我正在尝试使用client.has_what()api。似乎工作人员的负载不会立即反映出类似于状态UI页面上显示的内容。有时,has_what需要花费相当多的时间来反映任何数据。

是否有另一个api可用于确定自由工作人员的数量,然后可用于确定类似于UI正在使用的油门范围。