【问题标题】:multi-computer makePSOCKcluster on Windows: Building a step-by-step guideWindows 上的多计算机 makePSOCKcluster:构建分步指南
【发布时间】:2018-06-27 06:41:59
【问题描述】:

三天以来,我一直在尝试使用多台计算机构建集群,但失败了。所以现在我要试着吸引你们来为我解决我的问题。如果一切顺利,我希望我们可以生成一个分步指南,以用作将来执行此操作的参考,因为到目前为止,我还没有找到合适的参考来设置它(也许这是一项过于具体的任务?)

在我的例子中,让我们假设 Windows 7,使用 PuTTY 作为 SSH 客户端,并且“localhost”将作为主服务器。

此外,我们现在假设同一网络上只有两台计算机。我想这个过程很容易概括,如果我可以让它在两台计算机上运行,​​我可以让它在三台计算机上运行。所以我们将处理localhostremote-computer

这是我到目前为止收集到的(参考链接在底部)

  1. localhost 上安装 PuTTY。
  2. remote-computer 上安装 PuTTY
  3. remote-computer 上安装 SSH 服务器
  4. 为其分配监听端口? (我不确定这一步)
  5. localhost 上安装 R
  6. remote-computer 上安装相同版本的 R
  7. localhostremote-computer 的PATH 环境变量中添加R
  8. localhost运行下面的R代码

代码:

library(parallel)
cl <- makePSOCKcluster(c(rep("localhost", 2),
                         rep("remote-computer", 2)))

到目前为止,我已经完成了步骤 1-3,不确定是否需要执行 4,完成 5-7,而步骤 8 的代码只是无限期挂起。

当我检查我的 SSH 服务器日志时,我似乎没有从 localhost 访问 SSH 服务器。所以看来我的第一个问题是正确配置 SSH。有没有人成功做到这一点,您愿意分享您的专业知识吗?

编辑 哎呀:参考 http://www.milanor.net/blog/wp-content/uploads/2013/10/03.FirstStepinParallelComputing.pdf

R Parallel - connecting to remote cores

https://stat.ethz.ch/pipermail/r-sig-hpc/2010-October/000780.html

【问题讨论】:

  • 请注意,makePSOCKcluster 不使用 ssh 在 localhost 上启动工作程序,因此您不会期望在本地计算机的 SSH 服务器日志中看到任何内容。
  • 然而,我希望在远程机器上看到一些东西。在我写这个问题的时候,我什么也没看到。我会在今天下班之前发布更新。我想我已经接近了。

标签: r ssh parallel-processing putty


【解决方案1】:

充其量,这只是部分答案。我还没有建立集群,但这里描述的步骤很好地记录了我是如何做到这一点的。

配置:

  1. 在“远程计算机”上安装 PuTTY
  2. 在“远程计算机”上安装 SSH 服务器
  3. 在“远程计算机”上安装 R(使用与“本地主机”上相同版本的 R)
  4. 将 R 添加到 PATH

  5. 在“本地主机”上安装 PuTTY

  6. 在“本地主机”上安装 R
  7. 将 R 添加到 PATH

测试连接:第一阶段

  1. 从命令行运行

C:\PuTTYPath\plink.exe -pw [password] [username]@[remote_ip_address] Rscript -e rnorm(100)

(确认返回 100 个正态随机变量

  1. 从命令行运行

C:\PuTTYPath\plink.exe -pw [password] [username]@[remoate_ip_address] RScript -e parallel:::.slaveRSOCK() MASTER=[local_ip_address] PORT=100501 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE

(确认会话已在 SSH 服务器上启动,登录 'remote-computer')

测试连接:第二阶段

  1. 从 R 会话中运行

    system(paste0("C:/PuTTYPath/plink.exe -pw [password] ", "[username]@[remote_ip_address] ", "RScript -e rnorm(100)"))

    (确认返回 100 个正态随机变量)

  2. 从 R 会话中运行

    system(paste0("C:/PuTTY/plink.exe ", "-pw [password] ", "[username]@[remote_ip_address] ", "RScript -e parallel:::.slaveRSOCK() ", "MASTER=[local_ip_address] ", "PORT=100501 ", "OUT=/dev/null ", "TIMEOUT=2592000 ", "METHODS=TRUE ", "XDR=TRUE"))

(确认会话已在 SSH 服务器上启动并维护,并登录“远程计算机”

建立一个集群

  1. 从 R 会话中运行

    library(snow) cl <- makeCluster(spec = c("localhost", "[remote_ip_address]"), rshcmd = "C:/PuTTY/plink.exe -pw [password]", host = "[local_ip_address]")

(应在“远程计算机”上的 SSH 服务器日志上启动和维护会话。 理想情况下,该函数将在分配“cl”时完成)

建立集群是我失败的地方。我运行 makeCluster 并查看我的 SSH 服务器日志。它显示连接已建立,然后立即关闭。 makeCluster 永远不会完成运行,cl 没有被分配,我被困在如何继续下去。我什至不确定这是 R 问题还是配置问题。

编辑和解决:

无缘无故,我尝试使用snow 包运行它,如上面的“建立集群”部分所示。当我使用snow 包时,集群已经构建并稳定运行。不知道为什么我不能让它与parallel 包一起工作,但至少我有一些功能。

【讨论】:

  • 默认情况下,R需要在所有机器上安装相同的路径,因为默认情况下makeCluster在启动worker时使用master机器上Rscript的完整路径。如果它没有安装在同一个地方,您可以尝试使用 makeCluster homogeneous=FALSE 选项,这将导致它只使用“Rscript”,就像您在测试中所做的那样。如果你不设置homogeneous=FALSE,我认为R不需要在远程机器上的PATH中。
  • 我确保以相同的方式安装 R。但是,我发现我仍然需要将 R 添加到 PATH,因为当我在 R3.2.2 上运行 makeCluster 时,它坚持使用 R3.1.1 的路径(我检查过,R3.2.2 在我的 PATH 上)。将 R 添加到两台计算机上的 PATH 中,我只需指定 rscript = "RScript"。但是,通过精心设计,这些机器是同质的。使用 homogenous = TRUEhomogenous = FALSE 不会更改当前结果。我仍然看到我的本地机器连接到远程,然后立即终止连接。
  • 刚刚添加了一个编辑——我设法通过使用snow 包而不是parallel 包使集群工作。我不确定我是否受过足够的教育,知道为什么它在 snow 中有效,而在 parallel 中无效。
【解决方案2】:

对于那些正在寻找在 Windows 中跨多台计算机建立集群的人,@Benjamin 的回答几乎是正确的,您需要按照他的指示直到最后一步,即 ESTABLISH A CLUSTER,并确保前面的步骤都有效在您的计算机中。我的解决方案是基于包'Parallel'而不是'snow',它们本质上是相同的。

解决方案

代码模板:

machineAddresses <-list(list(host='[Server address]',user='[user name]',rscript="[The Rscript file in the server]",rshcmd="plink -pw [Your password]"))
cl <- makePSOCKcluster(machineAddresses,manual = F)

您必须在代码中填写所有 []。在我的电脑里是:

machineAddresses <-list(list(host='192.168.1.220',user='jeff',rscript="C:/Program Files/R/R-3.3.2/bin/Rscript",rshcmd="plink -pw qwer"))
cl <- makePSOCKcluster(machineAddresses,manual = F)

原因

在 Windows 中运行集群非常棘手,函数 makePSOCKcluster 通常无法按预期工作。使其工作的最简单方法是将 manual=F 更改为 manual=T 并手动创建工人。这是一个相关的帖子,它谈到了为什么函数makePSOCKcluster会永远挂起,我认为这两个帖子基本上卡在同一个地方。我还发布了对该问题的回答,以讨论如何使其发挥作用。

R Parallel - connecting to remote cores

【讨论】:

    【解决方案3】:

    由于我没有对 Jeff 的回答发表评论的声誉,因此我将其发布为答案:

    我发现使用 makePSOCKcluster 自动启动集群节点在 Windows 中不起作用的原因是内部 parallel 函数 newPSOCKnode 中的 argoutfile 参数包含在 shQuotes 中功能。这会导致 cmd.exe 和 Rscript.exe 的组合返回错误,从而导致 makePSOCKcluster 永远挂起。

    以下两个函数定义允许使用makePSOCKcluter自动启动集群节点,假设正确配置sshputty/plink进行基于密钥的无密码登录:

    makePSOCKcluster <- function (names, ...) 
    {
      if (is.numeric(names)) {
        names <- as.integer(names[1L])
        if (is.na(names) || names < 1L) 
          stop("numeric 'names' must be >= 1")
        names <- rep("localhost", names)
      }
      parallel:::.check_ncores(length(names))
      options <- parallel:::addClusterOptions(parallel:::defaultClusterOptions, list(...))
      cl <- vector("list", length(names))
      for (i in seq_along(cl)) cl[[i]] <- newPSOCKnode(names[[i]], 
                                                       options = options, rank = i)
      class(cl) <- c("SOCKcluster", "cluster")
      cl
    }
    
    newPSOCKnode <- function (machine = "localhost", ..., options = parallel:::defaultClusterOptions, 
                              rank) 
    {
      options <- parallel:::addClusterOptions(options, list(...))
      if (is.list(machine)) {
        options <- parallel:::addClusterOptions(options, machine)
        machine <- machine$host
      }
      outfile <- parallel:::getClusterOption("outfile", options)
      master <- if (machine == "localhost") 
        "localhost"
      else parallel:::getClusterOption("master", options)
      port <- parallel:::getClusterOption("port", options)
      setup_timeout <- parallel:::getClusterOption("setup_timeout", options)
      manual <- parallel:::getClusterOption("manual", options)
      timeout <- parallel:::getClusterOption("timeout", options)
      methods <- parallel:::getClusterOption("methods", options)
      useXDR <- parallel:::getClusterOption("useXDR", options)
      env <- paste0("MASTER=", master, " PORT=", port, " OUT=", 
                    #shQuote(outfile), " SETUPTIMEOUT=", setup_timeout, " TIMEOUT=", 
                    (outfile), " SETUPTIMEOUT=", setup_timeout, " TIMEOUT=", 
                    timeout, " XDR=", useXDR)
      arg <- "parallel:::.slaveRSOCK()"
      rscript <- if (parallel:::getClusterOption("homogeneous", options)) {
        shQuote(parallel:::getClusterOption("rscript", options))
      }
      else "Rscript"
      rscript_args <- parallel:::getClusterOption("rscript_args", options)
      if (methods) 
        rscript_args <- c("--default-packages=datasets,utils,grDevices,graphics,stats,methods", 
                          rscript_args)
      cmd <- if (length(rscript_args)) 
        paste(rscript, paste(rscript_args, collapse = " "), "-e", 
              #shQuote(arg), env)
              arg, env)
      #else paste(rscript, "-e", shQuote(arg), env)
      else paste(rscript, "-e", arg, env)
      renice <- parallel:::getClusterOption("renice", options)
      if (!is.na(renice) && renice) 
        cmd <- sprintf("nice +%d %s", as.integer(renice), cmd)
      if (manual) {
        cat("Manually start worker on", machine, "with\n    ", 
            cmd, "\n")
        utils::flush.console()
      }
      else {
        if (machine != "localhost") {
          rshcmd <- parallel:::getClusterOption("rshcmd", options)
          user <- parallel:::getClusterOption("user", options)
          cmd <- shQuote(cmd)
          cmd <- paste(rshcmd, "-l", user, machine, cmd)
        }
        if (.Platform$OS.type == "windows") {
          system(cmd, wait = FALSE, input = "")
        }
        else system(cmd, wait = FALSE)
      }
      con <- socketConnection("localhost", port = port, server = TRUE, 
                              blocking = TRUE, open = "a+b", timeout = timeout)
      structure(list(con = con, host = machine, rank = rank), class = if (useXDR) 
        "SOCKnode"
        else "SOCK0node")
    }
    

    我计划在有机会时使用更完整的设置说明更新此回复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-30
      • 1970-01-01
      • 2012-07-24
      • 2014-01-11
      • 1970-01-01
      相关资源
      最近更新 更多