R doParallel foreach 工作者超时错误并且永远不会返回

Posted

技术标签:

【中文标题】R doParallel foreach 工作者超时错误并且永远不会返回【英文标题】:R doParallel foreach worker timeout error and never returns 【发布时间】:2016-06-14 13:43:42 【问题描述】:

以下问题是与此处描述的问题相关的非常详细的问题。 Previous Question

使用 Ubuntu Server 14.04 LTS 64 位 Amazon 系统映像在带有 R 版本 3.2.3 的 c4.8xlarge(36 核)上启动。

考虑下面的代码

library(doParallel)
cl=makeCluster(35)
registerDoParallel(cl)

tryCatch(
  evalWithTimeout(
    foreach(i=1:10) %:%
      foreach(j=1:50) %dopar% 
        tryCatch(
          evalWithTimeout(
            set.seed(j)
            source(paste("file",i,".R", sep = "")) # File that takes a long time to run
            save.image(file=paste("file", i, "-run",j,".RData",sep=""))
          ,
          timeout=300); ### Timeout for individual processes
        , TimeoutException=function(ex) 
          return(paste0("Timeout 1 Fail ", i, "-run", j))

        )
      
  ,
  timeout=3600); ### Cumulative Timeout for entire process
, TimeoutException=function(ex) 

  return("Timeout 2 Fail")

)

stopCluster(cl)

请注意,两个超时异常都有效。我们注意到个别进程超时,如果有必要,累积进程超时。

但是,我们发现单个进程可以启动并且出于未知原因在 300 秒后不会超时。请注意,单个进程超时确保该进程不是“只需要很长时间”。结果,核心被这个单一进程占用并以 100% 的速度运行,直到达到 3600 秒的累积超时。请注意,如果累积超时未到位,进程及其核心将被无限期占用,foreach 循环将无限期继续。达到累积时间后,将返回“Timeout 2 Fail”并继续执行脚本。

问题:如果一个单独的工作进程“挂起”,以至于连单独的超时机制都不起作用,如何重新启动工作进程,以便它可以继续在并行处理?如果无法重新启动worker,是否可以在达到累积超时时以外的方式停止worker?这样做可以确保进程不会在只有一个“错误”进程在运行时继续长时间“等待”达到累积超时。

其他信息 一个“逃跑”的进程或“挂起”的工人被抓到了。使用 htop 查看进程,它的状态为 100% CPU 运行。以下链接是该进程的gdb回溯调用截图

backtrace screenshot

问题:是否在回溯中确定了“失控”进程的原因?

【问题讨论】:

我目前在运行 R/3.2.0 的大型计算集群上遇到了同样的问题。我为各个进程设置了超时异常,但也发现有些进程在设置时间后不会超时,原因不明。任何帮助将不胜感激。 【参考方案1】:

我多次尝试让 evalWithTimeout 在非常相似的环境中工作。我发现这非常有问题,特别是如果您使用数据库连接或全局变量。然而,对我来说效果很好的是创建一个使用setTimeLimit 的表达式。要正确使用它,您必须将它和您的函数一起包装在 中。这是一个例子:

foreach(...) %dopar% 
  withCallingHandlers( 
    setTimeLimit(360)
    # your function goes here, runs for 360 seconds, or fails
    , 
    error = function(e) 
    # do stuff to capture error messages here
    
  )

我使用 withCallingHandlers 是因为堆栈跟踪非常有用并且可以深入了解正在发生的事情。在我的错误函数中,我通常会适当地捕获详细的错误消息,这样我就可以查看发生了什么问题以及发生了什么问题。

总结一下:

    setTimeLimit 通常比 evalWithTimeout 更可靠 使用 withCallingsHandlers 为您提供了出色的错误处理选项和比 tryCatch 更详细的输出 请记住将错误消息保存在有用的地方并对其进行格式化,以便您了解实际情况。

【讨论】:

以上是关于R doParallel foreach 工作者超时错误并且永远不会返回的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中将 fread 与 foreach 和 doParallel 一起使用

在 R doParallel foreach 循环中运行 ovun.sample

使用 foreach 函数和 doParallel 库在 R 中嵌套 for 循环

使用 R doParallel 或 foreach 从 mysql 并行获取数据

在 R 中使用 doParallel 的 foreach 时,Windows Defender 的 CPU 使用率非常高

Foreach和doparallel而不是R中的for循环