2017-01-13 44 views
1

我試圖在本地主機上完美工作並行運行R.現在我想切換到多節點設置並在同一網絡中創建多個虛擬機。然而,當我試圖設置羣集時,出現以下錯誤:由於「無法打開連接」錯誤,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 = "") 

我也曾嘗試剛剛開放套接字在本地主機上,它失敗以及(但在本地主機集羣只適用),與同樣的錯誤信息:

socketConnection("localhost", port = 11056, blocking = TRUE, open = "a+b") 

只有當我添加服務器= TRUE選項,socketConnection的作品,但我不確定這個選項是否適合makeCluster以及如何設置它。

我已經全新安裝了Ubuntu Server 16.04,iptables規則爲空(ACCEPT all),ssh可以雙向運行,所以我不知道爲什麼它不起作用。

回答

1

當工作人員嘗試連接到主進程時,可能是因爲至少有一名工人無法解析主服務器的主機名(在您的示例中爲「ubuntu-r-node1」),因此出現socketConnection錯誤。主機的主機名默認使用Sys.info()['nodename']確定,如果有任何工作人員無法解析此名稱,他們將無法創建與主機的套接字連接,並且makeCluster將掛起。

一個常用的解決這個問題是使用makeCluster「主」選項來指定主正在執行的機器的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'ing啓動員工'192.168.42.26'和'192.168.42.32',並且工人將使用socketConnection連接回主人,返回的值爲nsl(Sys.info()['nodename'])

請注意,如果主站有防火牆,則makeCluster「端口」選項也很重要,因爲默認情況下端口是在11000到11999範圍內隨機選擇的。

0

看來,DNS也應該在兩個方向上工作。

例如,如果在我的例子第一主機(192.168.42.26)將有一個名稱「主機1」和第二主機(192.168.42.32)「主機2」,那麼這兩個

ssh host1 

(從主機2)

ssh host2 

(來自主機1)

應該工作運行的R型聚類。

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隧道,該隧道將成爲傳出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連接將該機器的端口映射回主站。

如果反向隧道的方法不適合你,我想你要問您的系統管理員,詳細瞭解哪些端口被封鎖等

我希望這是有道理的。

+1

謝謝你的回答。問題已經解決了(是DNS問題,我把它作爲一個單獨的答案發布),但是您提供的信息確實非常有用,我不知道有關revtunnel選項。 –

相關問題