无法打开并行群集的套接字

时间:2013-10-08 13:09:44

标签: r parallel-processing

我正在尝试使用parallel包,发现makeCluster无法完成。我已追踪到newPSOCKnode中的以下行:

con <- socketConnection("localhost", port = port, server = TRUE, 
    blocking = TRUE, open = "a+b", timeout = timeout)

该命令停止(授予默认超时值很大)。我怀疑这是因为我们的工作计算机上存在一些“过度热心的IT规则”,但欢迎任何有关如何跟踪(和修复)问题根源的建议。这是Windows7-64,“Enterprise”,R 3.0.1。

更多信息:在调试会话内部,我设置了timeout < - 10,但它仍然挂起 - 好像socketConnection被困在一个甚至无法检查超时值的地方。

这是我与Richie Cotton的数据相同的转储:

Browse[3]> ls.str()
arg :  chr "parallel:::.slaveRSOCK()"
cmd :  chr "\"C:/Users/carl.witthoft/Documents/R/R-3.0.1/bin/x64/Rscript\" -e \"parallel:::.slaveRSOCK()\" MASTER=localhost PORT=11017 OUT="| __truncated__
env :  chr "MASTER=localhost PORT=11017 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE"
machine :  chr "localhost"
manual :  logi FALSE
master :  chr "localhost"
methods :  logi TRUE
options : <environment: 0x000000000ccac6a0> 
outfile :  chr "/dev/null"
port :  int 11017
rank :  int 1
renice :  int NA
rscript :  chr "\"C:/Users/carl.witthoft/Documents/R/R-3.0.1/bin/x64/Rscript\""
timeout :  num 2592000
useXDR :  logi TRUE

除了不同的端口号,我认为一切都匹配。

下一个技巧:我打开一个shell并运行netsh advfirewall firewall add rule name="Open Port 11017" dir=in action=allow protocol=TCP localport=11017并得到一个“OK”响应。 我跑了netstat -a -n并找到了以下一行:

TCP 0.0.0.0:11017 0.0.0.0:0 LISTENING

但是makePSOCKcluster仍然在同一个地方停留。

NEXT: 我尝试从命令行运行R(通过cygwin bash),我得到的错误消息是Error in loadhistory(file) : no history mechanism available Execution halted,之后-C将我返回到R-prompt。

3 个答案:

答案 0 :(得分:8)

您所描述的是PSOCK群集的典型问题: makeCluster挂起。由于必须创建所有将执行“集群”实际工作的进程(称为“工作”进程),并且涉及使用将执行.slaveRSOCK函数,它将创建一个回到主服务器的套接字连接,然后执行slaveLoop函数,它最终将执行主服务器发送给它的任务。如果在启动任何工作进程时出现任何问题(并且相信我:很多可能会出错),主服务器将在执行socketConnection时挂起,等待工作人员连接到它,即使该工作人员可能已经死亡或从来没有成功过。

对于许多故障情况,使用outfile参数非常有用,因为它经常会显示导致工作进程死亡的错误,从而导致主服务器挂起。但如果没有显示任何内容,我会进入手动模式。在手动模式下,主服务器打印命令以启动每个工作程序,而不是执行命令本身。这是更多的工作,但它可以让您完全控制,如果需要,您甚至可以调试工人。

以下是一个例子:

> library(parallel)
> cl <- makePSOCKcluster(1, manual=TRUE, outfile='log.txt')
Manually start worker on localhost with
   '/usr/lib/R/bin/Rscript' -e 'parallel:::.slaveRSOCK()' MASTER=localhost
PORT=10187 OUT=log.txt TIMEOUT=2592000 METHODS=TRUE XDR=TRUE 

此时,您的R会话被挂起,因为它正在执行socketConnection,正如您所描述的那样。现在你的工作是打开一个新的终端窗口(命令提示符,或其他),然后粘贴该Rscript命令。一旦执行它,makePSOCKcluster应该返回,因为我们只请求一个工人。当然,如果出现问题,它将无法返回,但如果您很幸运,您将在终端窗口中收到错误消息,您将获得一条重要线索,希望能够解决您的问题。如果你没那么幸运,那么Rscript命令也会挂起,你将不得不深入潜水。

要调试worker,您不需要执行显示的Rscript命令,因为您需要一个交互式会话。相反,您使用以下命令启动R会话:

$ R --vanilla --args MASTER=localhost PORT=10187 OUT=log.txt TIMEOUT=2592000 METHODS=TRUE XDR=TRUE

在该R会话中,您可以在.slaveRSOCK函数上放置一个断点,然后执行它:

> debug(parallel:::.slaveRSOCK)
> parallel:::.slaveRSOCK()

现在您可以开始逐步执​​行代码,可能会在slaveLoopmakeSOCKmaster函数上设置断点。在您的情况下,我假设它将挂起尝试创建套接字连接,在这种情况下,您的问题的标题将是适当的。

有关此类问题的详细信息,请参阅my answer to a similar question.

<强>更新

既然已经解决了这个特殊问题,我可以添加两个调试makePSOCKcluster问题的提示:

  • 检查.Rprofile中的任何内容是否只能以交互模式运行
  • 在Windows上,使用Rterm命令而不是Rgui,这样您就更有可能看到使用outfile=''的错误消息和输出。

答案 1 :(得分:3)

测试1:明显的命令是否有效?

library(parallel)    
cluster <- makePSOCKcluster("localhost")    
parSapply(cluster, 1:5, sqrt)
stopCluster(cluster)

测试2:您的端口是否被阻止?

根据?makeCluster,默认端口为10187。请咨询您的网络管理员,了解该端口是否已打开。

测试3:传递给socketConnection的变量看起来是否正确?

如果我执行debugonce(parallel:::newPSOCKnode),然后在调用socketConnection之前单步执行,那么工作区看起来就是这样:

ls.str()
arg :  chr "parallel:::.slaveRSOCK()"
## cmd :  chr "\"C:/PROGRA~1/R/R-215~1.2/bin/x64/Rscript\" -e \"parallel:::.slaveRSOCK()\" MASTER=localhost PORT=10187 OUT=/dev/null TIMEOUT=2"| __truncated__
## env :  chr "MASTER=localhost PORT=10187 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE"
## machine :  chr "localhost"
## manual :  logi FALSE
## master :  chr "localhost"
## methods :  logi TRUE
## options : <environment: 0x0000000010bf2518> 
## outfile :  chr "/dev/null"
## port :  num 10187
## rank :  int 1
## renice :  int NA
## rscript :  chr "\"C:/PROGRA~1/R/R-215~1.2/bin/x64/Rscript\""
## timeout :  num 2592000
## useXDR :  logi TRUE

你是否收到相同的内容?

答案 2 :(得分:2)

好吧,我不觉得自己是个白痴。

我回到“软件调试的三个R”(重试,重启,重新加载),重新启动系统并成功完成手动工作者启动后,我尝试创建一个manual=FALSE的群集,并立即那里也取得了成功。

编辑:我应该明确指出,将.Rprofileloadhistory()更改为if(interactive() ) loadhistory()对于成功使用cluster函数至关重要。

我非常感谢里奇和史蒂夫提出的所有有用的意见和建议。我当然在“引擎盖下”学到了很多东西,所以至少对我而言,这种体验非常积极。

(所以我不知道WindowsOS的东西或破坏的电话是怎么回事的,但一切都很好,结束了)