Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
parlappy循环中多个文件在R中的curl内存使用_R_Amazon Web Services_Ubuntu_Curl_Amazon Ec2 - Fatal编程技术网

parlappy循环中多个文件在R中的curl内存使用

parlappy循环中多个文件在R中的curl内存使用,r,amazon-web-services,ubuntu,curl,amazon-ec2,R,Amazon Web Services,Ubuntu,Curl,Amazon Ec2,我有一个项目,在ec2上下载约2000万个多线程PDF。我最精通R,这是一次性的,所以我最初的评估是,bash脚本编写节省的时间不足以证明花在学习曲线上的时间是合理的。所以我决定从R脚本中调用curl。该实例是一台c4.8X大型rstudio服务器,位于ubuntu上,拥有36个内核和60 Gig内存 无论用什么方法,我都试过,它都能相当快地运行到最大内存。它运行正常,但我担心交换内存会减慢速度。curl_download或curl_fetch_disk的运行速度比native download

我有一个项目,在ec2上下载约2000万个多线程PDF。我最精通R,这是一次性的,所以我最初的评估是,bash脚本编写节省的时间不足以证明花在学习曲线上的时间是合理的。所以我决定从R脚本中调用curl。该实例是一台c4.8X大型rstudio服务器,位于ubuntu上,拥有36个内核和60 Gig内存

无论用什么方法,我都试过,它都能相当快地运行到最大内存。它运行正常,但我担心交换内存会减慢速度。curl_download或curl_fetch_disk的运行速度比native download.file函数快得多(每0.05秒一个pdf,而不是0.2秒一个pdf),但这两个函数都以极快的速度运行到最大内存,然后似乎用空文件填充目录。对于本机函数,我通过大量使用try()和invisible()抑制输出来处理内存问题。这似乎对卷曲包毫无帮助

如果有人能帮我,我有三个相关的问题

(1) 我对内存使用方式的理解是否正确,因为不必要的内存交换会导致脚本速度减慢

(2) curl\u fetch\u磁盘应该是直接写入磁盘的,有人知道为什么它会占用这么多内存吗

(3) 在R中有什么好方法可以做到这一点,还是我最好学习一些bash脚本

当前使用curl\u下载的方法

getfile_sweep.fun <- function(url
                          ,filename){
  invisible(
    try(
      curl_download(url
                ,destfile=filename
                ,quiet=T
      )
    )
  )
}
getfile_sweep.fun注意:

1-我没有这样强大的系统,所以我不能复制提到的每一个问题

2-此处总结了所有评论

3-据称,机器已收到升级:
EBS到以6000 IOPs/秒
速度配置的SSD,但问题仍然存在

可能的问题:

A-如果内存交换开始发生,那么您就不再纯粹使用
RAM
,我认为
R
将越来越难找到可用的内存空间

B-工作负载和完成工作负载所需的时间,与内核数量相比

c-
并行
设置和
分叉群集

可能的解决方案和故障排除:

B-限制内存使用

C-限制芯数

D-如果代码在小型计算机(如personal desktop)上运行良好,问题在于如何设置并行使用,或者使用fork群集

仍需尝试的事项:

A-一般来说,在
并行
中运行作业会产生
开销
,现在您拥有的
内核越多,您会看到更多的影响。当你通过许多只需很少时间的作业时(想想比秒还短),这将导致与不断推送作业相关的
开销增加。尝试将
核心限制为8
,就像您的桌面一样,然后尝试您的代码?代码运行正常吗?如果是,则在增加程序可用的内核时尝试增加工作负载

从内核数量和ram数量的低端开始,随着工作负载的增加而增加,看看下降发生在哪里

B-我将发布一篇关于R中的并行性的总结,这可能会帮助你抓住我们遗漏的东西

工作内容:
限制内核的数量已经解决了这个问题。正如OP提到的,他还对代码做了其他更改,但我无权访问这些更改。

您可以使用异步接口。下面是一个简短的例子:

cb_done <- function(resp) {
    filename <- basename(urltools::path(resp$url))
    writeBin(resp$content, filename)
}

pool <- curl::new_pool()
for (u in urls) curl::curl_fetch_multi(u, pool = pool, done = cb_done)
curl::multi_run(pool = pool)

cb_done有人认为,记住写入硬盘驱动器是系统操作中最慢的部分之一。那么,你是说,问题可能是curl试图写入磁盘的速度比硬盘驱动器的速度快,并且它将硬盘保存在内存中?每个pdf大约30KB。如果我每秒得到20个文件,我需要6MB/s的写入速度。AWS表明我的ec2和卷应该能够处理这个问题,还是我弄错了?1-您是最新的,但如果内存交换开始发生,那么您就不再纯粹使用RAM,我认为R将越来越难找到可用的内存空间,我也在研究这个问题。(我不确定)2-您是否尝试过使用wb模式的native download.file?已将EBS提高到以6000 IOPs/秒的速度配置SSD,因此写入磁盘不应成为瓶颈。同样的问题。现在剧本已经过时了。我开始认为这与fork集群有关。它可以在几分钟或几秒钟内运行高达60GB的ram。这不可能来自PDF。我也无法在我的桌面上重现这个问题(8核64gb macos sierra)。是的,我越来越确信这就是并行使用的设置方式。在stackexchange上发布的新功能,因此我需要花费几秒钟才能找到提高CPU使用率的方法。基本上,它是非常低的,直到循环结束或内存达到最大值,然后它会出现峰值。我已经设法让脚本再次运行,但我仍然觉得它可以运行得更快。我将很快发布更新的代码。建议C有效地解决了内存问题。虽然我已经实现了许多其他的更改,但我认为使用makeCluster(round(detectCores()*.7),type=“FORK)可以限制内核的数量已经留下了足够的资源来处理开销,内存使用率保持在8-9 GB左右。虽然还有其他问题,但我认为它们与原始帖子中描述的问题是不同的,我相信@dirty_feri已经解决了这个问题。我将很快在原始帖子中包含更新的代码。我很高兴听到事情进展顺利如果内存问题得到解决,请接受我的答案并打勾,然后就您可能遇到的任何其他问题打开另一篇文章。在阅读了有关curl\u fetch\u multi的文档后,这是一个有趣的建议。初始下载已完成,但我将在
len <- nrow(url_sweep.df)

gc.vec <- unlist(lapply(0:35, function(x) x + seq(
from=100,to=len,by=1000)))

gc.vec <- gc.vec[order(gc.vec)]

start.time <- Sys.time()

ptm <- proc.time()
cl <- makeCluster(detectCores()-1,type="FORK")
invisible(
  parLapply(cl,1:len, function(x){
    invisible(
      try(
        getfile_sweep.fun(
          url = url_sweep.df[x,"url"]
          ,filename = url_sweep.df[x,"filename"]
        )
      )
    )
    if(x %in% gc.vec){
      gc()
    }
  }
  )
)
stopCluster(cl)
Sweep.time <- proc.time() - ptm
cb_done <- function(resp) {
    filename <- basename(urltools::path(resp$url))
    writeBin(resp$content, filename)
}

pool <- curl::new_pool()
for (u in urls) curl::curl_fetch_multi(u, pool = pool, done = cb_done)
curl::multi_run(pool = pool)