我正在尝试并行运行R,这在本地主机上非常有效。现在我想切换到多节点设置,并在同一网络中创建了几个虚拟机。然而,当我试图设置集群时,它失败了,并出现以下错误:
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双向工作,所以我不知道为什么它不工作。
如果这里涉及防火墙问题,那么作为的替代方案
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隧道,它将是从主服务器到工作服务器的传出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连接将端口从该机器映射回主进程。
如果这种反向隧道方法不适用于您,我认为您必须向您的系统管理员询问有关哪些端口被阻止等的更多详细信息。
我希望这是有道理的。
当工作进程尝试连接到主进程时,会发生socketConnection
错误,可能是因为至少有一个工作进程无法解析主进程的主机名,在您的示例中为"ubuntu-r-node1"。默认情况下,主机名是使用Sys.info()['nodename']
确定的,如果任何工作程序无法解析此名称,则它们将无法创建到主机的套接字连接,并且makeCluster
将挂起。
解决此问题的常见方法是使用makeCluster
"master"选项来指定执行master的机器的IP地址。这里有一种方法可以使用nsl
函数(在Windows上不可用)在master而不是worker上查找master的主机名:
cl <- makePSOCKcluster(c(rep('192.168.42.26', 2),
rep('192.168.42.32', 2)),
master=nsl(Sys.info()['nodename']),
outfile='')
通过为工作进程和主进程指定IP地址,您可以大大减少DNS问题。在本例中,master将通过ssh‘ing到‘192.168.42.26’和‘192.168.42.32’来启动worker,worker将使用socketConnection
和nsl(Sys.info()['nodename'])
返回的值连接回master。
请注意,如果主机有防火墙,makeCluster
"端口"选项也很重要,因为默认情况下,端口是在11000到11999之间随机选择的。
看来,DNS也应该双向工作。
例如,如果在我的示例中第一个主机(192.168.42.26)的名称为"host1",第二个主机(192192.168.42.32)为"host2",那么两个
ssh host1
(来自主机2)
和
ssh host2
(来自主机1)
应该可以运行R集群。