3

我想使用管道工包来执行一些灵活的并行处理,并希望它可以在 node.js 框架中工作,这样它就不会阻塞......

我有以下管道工文件。

# myfile.R

#* @get /mean
normalMean <- function(samples=10){
  Sys.sleep(5)
  data <- rnorm(samples)
  mean(data)
}

我还按照此处的建议安装了 pm2 http://plumber.trestletech.com/docs/hosting/

我也做了同样的run-myfile.sh文件,即

#!/bin/bash
R -e "library(plumber); pr <- plumb('myfile.R'); pr\$run(port=4000)"

并按照建议使其可执行...

我已经使用 pm2 启动了

pm2 start /path/to/run-myfile.sh

并想测试它是否可以执行非阻塞node.js框架...

通过打开另一个 R 控制台并运行以下命令...

foo <- function(){
    con <- curl::curl('http://localhost:4000/mean?samples=10000',handle = curl::new_handle())
    on.exit(close(con))
    return(readLines(con, n = 1, ok = FALSE, warn = FALSE))
}

system.time(for (i in seq(5)){
    print(foo())
})

也许这是我对node.js非阻塞框架如何工作的误解,但在我看来,最后一个循环应该只需要 5 秒多一点。但这似乎需要 25 秒,这表明一切都是顺序的,而不是并行的。

我如何使用水管工包来实现这种非阻塞性质?

4

2 回答 2

3

不幸的是,pm2 无法为您平衡 R 进程的负载。R 是单线程的,并且实际上并没有像 NodeJS 那样允许它以异步方式运行的库(目前),所以在今天的管道工中并没有很多很好的方法来并行化这样的代码。最好的选择是运行多个管道工 R 后端并在它们之间分配流量。请参阅此处的“负载平衡”部分:http: //plumber.trestletech.com/docs/docker-advanced

于 2016-08-02T03:54:45.250 回答
-2

基本上并发请求由 httpuv 排队,因此它本身并不高效。作者推荐了多个 docker 容器,但它可能很复杂并且需要响应。

还有其他技术,例如 Rserve 和 rApache。Rserve fork proesses 并且可以将 rApache 配置为 pre-fork 以处理并发请求。

请参阅以下帖子进行比较

https://www.linkedin.com/pulse/api-development-r-part-i-jaehyeon-kim/ https://www.linkedin.com/pulse/api-development-r-part-ii-jaehyeon-金/

于 2017-12-07T09:16:55.637 回答