使用分布式dask,如何从队列提供的长时间运行任务生成未来

使用分布式dask,如何从队列提供的长时间运行任务生成未来,dask,dask-distributed,Dask,Dask Distributed,我使用的是一个磁盘分布式长时间运行任务,与本例类似,长时间运行的辅助任务从队列中获取输入,如tensorflow示例中所示,并将其结果传递到输出队列。(我没有看到dask最新版本示例中使用的通道) 我可以看到如何分散一个列表,并应用一个映射来生成一个未来列表,将输入数据推送到workers输入队列中 def transfer_dask_to_worker(batch): worker = get_worker() worker.tensorflow_queue.put(batch

我使用的是一个磁盘分布式长时间运行任务,与本例类似,长时间运行的辅助任务从队列中获取输入,如tensorflow示例中所示,并将其结果传递到输出队列。(我没有看到dask最新版本示例中使用的通道)

我可以看到如何分散一个列表,并应用一个映射来生成一个未来列表,将输入数据推送到workers输入队列中

def transfer_dask_to_worker(batch):
    worker = get_worker()
    worker.tensorflow_queue.put(batch)

data = [1,2,3,4] 

future_data = e.scatter(data)

tasks = e.map(transfer_dask_to_worker, future_data ,
     workers=dask_spec['worker'], pure=False)
现在,如果我们等待工作者使用任务,所有结果都将在工作者的输出队列中。我们可以使用

def transfer_worker_to_dask(arg):
    worker = get_worker()
    return worker.output_queue.get()

results = e.map(transfer_worker_to_dask,range(len(tasks)))
只要我们手动处理排序,等待所有辅助任务完成,然后再调用它们,这就可以正常工作

我们如何将产出期货与投入的下游联系起来?对于长时间运行的任务,是否有一种方法可以在可以收集回调度程序任务的工作进程上创建未来

我尝试让transfer_dask_to_worker(批处理)也查询输出队列并返回结果:

def transfer_dask_to_worker_and_return(batch):
    worker = get_worker()
    worker.tensorflow_queue.put(batch)
    return worker.output_queue.get()
这适用于短名单,但由于取消了约1000个项目的期货,这项操作开始失败

提前谢谢

注意:blogpost是实验性的。这里有几种方法,我不会局限于这种模式

让我们从这个具体问题开始:

我们如何将产出期货与投入的下游联系起来?对于长时间运行的任务,是否有一种方法可以在可以收集回调度程序任务的工作进程上创建未来

这里最简单的解决方案可能是分散本地数据,然后将其放入一个数据库中。因此,如果您有一个TensorFlow代码在生成某些结果时调用的函数,那么该函数可能会将本地数据分散到未来(这实际上并没有移动数据,它只是让Dask工作者开始跟踪数据),然后将未来放入一个分布式队列。将未来放在队列中可以让Dask中的其他客户机和工作人员知道数据的存在,并在必要时将其取下

from dask.distributed import Queue
results_q = Queue()

def tf_result_ready(result):
    future = get_worker().scatter(result)
    results_q.put(future)
然后,您可以坐在客户端代码中,在结果可用时从此队列中提取结果:

for _ in range(n_blocks):
    future = results_q.get()
    # do stuff with future like submit or gather

这个解决方案肯定有效。谢谢你的帮助。然而,让TensorFlow(v1.4)在Dask分布式工作程序中表现良好仍然是一个挑战。在调用free期间,我定期但不可重复地在对TF Adam优化器的工作任务内部调用中生成segfaults(sig11)。相同的图形和优化器在本地运行良好。您可能需要验证TensorFlow是否在多线程环境中运行良好。如果没有,那么您可能希望更改dask工作进程,使其具有更多的进程,每个进程具有一个线程。这是一个很好的建议。TF被认为是处理线程的,但有一些参考文献指出,从python来看,这是多么困难。我正在用dask worker启动dask分布式worker--nthreads 1,但我怀疑您还有其他想法。