如何构造一个Dask应用程序来处理来自队列的固定数量的输入?

如何构造一个Dask应用程序来处理来自队列的固定数量的输入?,dask,dask-distributed,Dask,Dask Distributed,我们有一个实现以下内容的要求。给定将提供已知数量消息的Redis通道: 对于从通道消耗的每条消息: 从Redis获取JSON文档 解析JSON文档,提取结果对象列表 跨所有结果对象聚合以生成单个结果 我们希望将步骤1和步骤2分发给许多工作人员,并避免将所有结果收集到内存中。我们还希望显示这两个步骤的进度条 然而,我们无法找到一种很好的方法来构造应用程序,这样我们就可以看到进展并在系统中保持工作的进行,而不会因为不合适的时候而阻塞 例如,在步骤1中,如果我们从Redis通道读入一个队列,那么我

我们有一个实现以下内容的要求。给定将提供已知数量消息的Redis通道:

  • 对于从通道消耗的每条消息:

    • 从Redis获取JSON文档
    • 解析JSON文档,提取结果对象列表
  • 跨所有结果对象聚合以生成单个结果

  • 我们希望将步骤1和步骤2分发给许多工作人员,并避免将所有结果收集到内存中。我们还希望显示这两个步骤的进度条

    然而,我们无法找到一种很好的方法来构造应用程序,这样我们就可以看到进展并在系统中保持工作的进行,而不会因为不合适的时候而阻塞

    例如,在步骤1中,如果我们从Redis通道读入一个队列,那么我们可以将该队列传递给Dask,在这种情况下,我们开始处理传入的每条消息,而不等待所有消息。但是,如果使用队列,我们看不到显示进度的方法(可能是因为队列通常具有未知的大小?)

    如果我们从Redis通道收集到一个列表,并将其传递给Dask,那么我们可以看到进度,但我们必须等待Redis发出的所有消息,然后才能开始处理第一条消息


    有没有一种推荐的方法来解决这类问题?

    如果您的Redis频道是并发访问安全的,那么您可能会提交许多期货以从该频道中提取元素。这些将在不同的机器上运行

    from dask.distributed import Client, progress
    client = Client(...)
    
    futures = [client.submit(pull_from_redis_channel, ..., pure=False) for _ in range(n_items)]
    futures2 = client.map(process, futures)
    
    progress(futures2)
    

    很不错的!我使用的Redis pub/sub对此不起作用,但LPUSH+BLPOP的作用类似于点-点队列,并且与上述方法非常配合,谢谢