如何忽略任务失败的工人并将其任务重新分配给其他工人?

时间:2019-03-27 19:12:25

标签: python distributed-computing dask dask-distributed

我正在使用client.map在N个单线程工作器(在N台计算机上)的池上运行一个函数,其中一个工作器失败。我想知道是否有一种方法可以自动处理工作程序引发的异常,将失败的任务重新分配给其他工作程序,并从池中忽略或排除它?

我尝试使用下面显示的方法来模拟问题。为了使一个工作人员失败,我在my_function中引发了一个OSError,它像这样client.map提交给futures = client.map(my_function, range(100))。在我的示例中,“ Computer123”上的工作程序将失败。为了处理my_function引发的异常,我在exception_handler中使用sys.exit。因此,当任务在工作线程上失败时,将调用sys.exit。结果是,当客户端重新分发其失败的任务时,不良工作程序的distributed.nanny会捕获故障并重新启动工作程序。但是一旦坏员工再次备份,由于它仍在池中,它将再次接收任务。它再次失败,然后重复该过程。随着故障的继续,最终其他工人将完成所有任务。如果我能够自动处理来自“ Computer123”之类的不良工人的异常并将其从池中删除,那将是理想的选择。也许我只需要将它从游泳池中删除?

@exception_handler
def my_function(x):
  import socket 
  import time
  time.sleep(5)
  if socket.gethostname() == 'Computer123':
    raise(OSError)
  else:
    return x**2

def exception_handler(orig_func):
  def wrapper(*args,**kwargs):
    try:
      return orig_func(*args,**kwargs)
    except:
      import sys
      sys.exit(1)
  return wrapper

1 个答案:

答案 0 :(得分:0)

作为一种解决方法,您可以保留一个坏工人字典,在每次您确定它不好时(可能在它引发一定数量的异常之后),都​​将主机名添加到该字典中。

然后,当您要发出某些任务时,请检查它是否在有问题的列表中。像这样:

  if socket.gethostname() in badHosts:
    skip
  else:
    do_something()

如果您可以提供有关如何管理连接到的池的更多详细信息,我也许可以提供一些有关如何直接删除它们的更多建议,而不必每次都进行检查。