parlappy循环中多个文件在R中的curl内存使用
我有一个项目,在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下载的方法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
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)