【问题标题】:Future solutions未来的解决方案
【发布时间】:2018-07-25 07:24:28
【问题描述】:

我正在处理一个大型数据集,我用它来进行某些计算。由于它是一个庞大的数据集,我正在使用的机器完成这项工作的时间过长,因此我决定使用 future 包来在多台机器之间分配工作并加快计算速度。 所以,我的问题是,通过未来(使用 putty 和 ssh)我可以连接到那些机器(并行),但工作本身正在做主要的工作,没有任何分发。也许您可以提出一些解决方案:

  • 如何让它在所有机器上工作;
  • 还有,如何检查进程是否正常工作(我的意思是某些功能或任何有助于验证这些功能的功能,如果存在的话)。

我的代码:

library(future)
workers <- c("000.000.0.000", "111.111.1.111")
plan(remote, envir = parent.frame(), workers= workers, myip = "222.222.2.22")
start <- proc.time()
cl <- makeClusterPSOCK(
 c("000.000.0.000", "111.111.1.111"), user = "...", 
rshcmd = c("plink", "-ssh", "-pw",  "..."),  
rshopts = c("-i", "V:\\vbulavina\\privatekey.ppk"),
homogeneous = FALSE))
setwd("V:/vbulavina/r/inversion")
a <- source("fun.r")
f <- future({source("pasos.r")})
l <- future({source("pasos2.R")})
time_elapsed_parallel <- proc.time() - start
time_elapsed_parallel

f 和 l 对象应该并行完成,但主机正在完成所有工作,所以如果我能做一些关于它的事情,我有点困惑。

PS:我尝试了plan()remote, multiprocess, multisession, cluster,但什么也没有。

PS2:我的本地机器是 Windows,并尝试连接到 Kubuntu 和 Debian(所有这些机器都关闭了防火墙)。

提前谢谢。

【问题讨论】:

  • @Axeman 问题是计划代码对我没有任何作用,因为没有它有连接,但机器之间没有分配
  • @Axeman 所以是的,plan(remote, envir = parent.frame(), workers= workers, myip = "192.168.2.48") 我试过这个,Error in socketConnection("localhost", port = port, server = TRUE, blocking = TRUE, : reached elapsed time limit 出现错误
  • @Axeman 哦,对不起,你是对的!
  • @Axeman 所以workers 只是我想用于连接的机器IP

标签: r windows ubuntu debian future


【解决方案1】:

future 的作者在这里。首先,确保您可以设置 PSOCK 集群,即通过 SSH 连接到两个 worker 并在它们上运行 Rscript。你这样做:

library(future)
workers <- c("000.000.0.000", "111.111.1.111")
cl <- makeClusterPSOCK(workers, user = "...",
                       rshcmd = c("plink", "-ssh", "-pw",  "..."),
                       rshopts = c("-i", "V:/vbulavina/privatekey.ppk"),
                       homogeneous = FALSE)
print(cl)
### socket cluster with 2 nodes on hosts '000.000.0.000', '111.111.1.111'

(如果上述makeClusterPSOCK() 停止运行或不起作用,请添加参数verbose = TRUE 以获取更多信息 - 请随时在此处报告。)

接下来,在 PSOCK 集群设置后,告诉未来的系统并行处理这两个工作线程:

plan(cluster, workers = cl)

测试期货实际上是远程解决的,例如

f <- future(Sys.info()[["nodename"]])
print(value(f))
### [1] "000.000.0.000"

我留下了剩下的部分,这也需要调整,现在让我们确保先让工作人员启动并运行。

继续,在并行处理中使用source() 会使事情变得复杂,尤其是在不同机器上进行并行化时。例如,在另一台机器上调用source("my_file.R") 要求文件my_file.R 在该机器上也可用。即使是这样,当涉及到需要导出到外部机器的变量的自动识别时,它也会使事情变得复杂。更安全的方法是将所有代码合并到主脚本中。说了这么多,你可以尝试替换:

f <- future({source("pasos.r")})
l <- future({source("pasos2.R")})

futureSource <- function(file, envir = parent.frame(), ...) {
  expr <- parse(file)
  future(expr, substitute = FALSE, envir = envir, ...)
}

f <- futureSource("pasos.r")
l <- futureSource("pasos2.R")

只要pasos.rpasos2.R 不在内部调用source(),这个c/应该可以工作。

顺便说一句,您使用的是哪个版本的 Windows?因为使用最新的 Windows 10,您已经内置了对 SSH 的支持,您不再需要使用 PuTTY。

2018 年 7 月 31 日更新:继续回答有关在期货中使用 source() 的问题。

【讨论】:

  • 非常感谢,正如你所说,我昨天通过verbose = TRUE 获得了机器之间的连接,并通过从 ubuntu 机器获取私钥并与 Windows 共享它们(顺便说一句,它是Windows 7的)。之后发生的错误,是关于更改plan(multiprocess),我试图更改计划,但它给了我无法将它与整数一起使用的错误,如果我没记错的话,bc 不能说当然,因为我前面没有我的计算机。就是这样,有 100% 的连接,但是 future 内部的代码没有被执行。
  • (1) 您不需要在机器之间共享私有 SSH 密钥 - 只有公共密钥。 (2) 我上面给出的plan(cluster, workers = cl) 例子是你如何设置两个worker;这是您唯一需要的plan()。如果你想在这两台机器上运行,比如说,四个工人,使用workers &lt;- rep(c("000.000.0.000", "111.111.1.111"), each = 4L)。 (3) 是的,我不希望您的 future(source(...)) 调用有效,但是当您确认我建议的 plan() 对您有效时,让我们讨论一下。
  • 好的,谢谢。对公众来说,它不起作用。试了好几次,都得到了私网的连接。
  • 嗯..好吧。请确认 f &lt;- future(Sys.info()[["nodename"]])value(f) 在我的示例中工作。
  • 抱歉耽搁了,我出现了一些问题。所以,f &lt;- future(Sys.info()value(f) 工作,我得到的结果是"cluster01"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-30
相关资源
最近更新 更多