我试图并行运行R,它在localhost上完美运行。现在我想切换到多节点设置并在同一网络中创建多个虚拟机。但是,当我尝试设置群集时,它会因以下错误而失败:
Error in socketConnection(master, port = port, blocking = TRUE, open = "a+b", :
cannot open the connection
Calls: <Anonymous> ... doTryCatch -> recvData -> makeSOCKmaster ->
socketConnection
In addition: Warning message:
In socketConnection(master, port = port, blocking = TRUE, open = "a+b", :
ubuntu-r-node1:11056 cannot be opened
最小可重复的例子:
library("parallel")
cl <- makeCluster(c(rep("192.168.42.26",2),rep("192.168.42.32",2)),outfile = "")
我还尝试在localhost上打开套接字,但它也失败了(但是localhost上的集群只能工作),并出现相同的错误消息:
socketConnection("localhost", port = 11056, blocking = TRUE, open = "a+b")
仅当我添加 server = TRUE 选项时,socketConnection才有效,但我不确定此选项是否适用于makeCluster以及如何设置它。
我有新安装的Ubuntu Server 16.04,iptables规则为空(ACCEPT all),ssh可以双向工作,所以我不知道它为什么不起作用。
答案 0 :(得分:1)
当工作人员尝试连接到主进程时发生socketConnection
错误,可能是因为至少有一个工作人员无法解析主人的主机名,即&#34 ; ubuntu的-R节点1&#34;在你的例子中。默认情况下,主人的主机名是使用Sys.info()['nodename']
确定的,如果任何工作人员无法解析此名称,他们将无法创建与主服务器的套接字连接,并且makeCluster
会挂起。
此问题的一个常见解决方法是使用makeCluster
&#34; master&#34;用于指定主机正在执行的机器的IP地址的选项。以下是使用nsl
函数(在Windows上不可用)在主服务器而不是工作程序上查找主服务器主机名的方法:
cl <- makePSOCKcluster(c(rep('192.168.42.26', 2),
rep('192.168.42.32', 2)),
master=nsl(Sys.info()['nodename']),
outfile='')
通过为工作人员和主人指定IP地址,DNS问题的问题要少得多。在这个例子中,主人将通过ssh&#194; 192.168.42.26&#39;启动工作人员。和&#39; 192.168.42.32&#39;,工作人员将使用socketConnection
与nsl(Sys.info()['nodename'])
返回的值连接回主人。
请注意makeCluster
&#34;端口&#34;如果主服务器具有防火墙,则选项也很重要,因为默认情况下,端口是在11000到11999范围内随机选择的。
答案 1 :(得分:1)
如果此处涉及防火墙问题,则替代:
library("parallel")
workers <- c(rep("192.168.42.26",2), rep("192.168.42.32",2))
cl <- makeCluster(workers, outfile = "")
相当于:
cl <- makePSOCKcluster(workers, outfile = "")
您可以尝试使用:
library("future")
cl <- makeClusterPSOCK(workers, revtunnel = TRUE, outfile = "", verbose = TRUE)
后者将设置一个所谓的反向SSH隧道,它将是一个&#34;内部&#34;从master到worker的传出SSH连接的一部分。例如,如果防火墙阻止工作者连接回主parallel::makePSOCKcluster()
,因为端口范围被阻止,那么future::makeClusterPSOCK(..., revtunnel = TRUE)
可以解决该问题。 verbose=TRUE
输出应显示如下内容:
Starting worker #1 on '192.168.42.26': 'ssh' -R 11356:localhost:11356 192.168.42.26 "'Rscript' --default-packages=datasets,utils,grDevices,graphics,stats,methods -e 'parallel:::.slaveRSOCK()' MASTER=localhost PORT=11356 OUT= TIMEOUT=2592000 XDR=TRUE"
Waiting for worker #1 on '192.168.42.26' to connect back
Connection with worker #1 on '192.168.42.26' established
[...]
这表明,就这个工人192.168.42.26
所知,它正连接回它认为在同一台机器上运行的主进程(MASTER=localhost:11356
),这是因为反向SSH隧道(-R 11356:localhost:11356
)通过SSH连接将该机器的端口映射回主服务器。
如果这种反向隧道方法对您不起作用,我认为您必须向您的系统管理员询问有关哪些端口被阻止等的更多详细信息。
我希望这是有道理的。
答案 2 :(得分:0)
看来,DNS也应该在两个方向都有效。
例如,如果我的示例中的第一个主机(192.168.42.26)有一个名称&#39; host1&#39;和第二个主机(192.168.42.32)&#39; host2&#39;,然后两个
ssh host1
(来自host2)
和
ssh host2
(来自host1)
应该可以运行R cluster。