我有一个项目可以在ec2上下载大约2000万个多线程PDF文件。我最精通R并且它是一次性的,所以我最初的评估是,bash脚本编写的时间节省不足以证明花在学习曲线上的时间是合理的。所以我决定只在R脚本中调用curl。该实例是一个c4.8xlarge,rstudio服务器,超过ubuntu,有36个内核和60 GB的内存。
我尝试过的任何方法都可以很快地达到最大值。它运行正常,但我担心交换内存正在减慢速度。 curl_download或curl_fetch_disk的工作速度比本机的download.file函数快得多(每0.05秒一次pdf,相对于.2),但这些都快速运行到最大内存极,然后似乎填充目录用空文件。使用本机函数,我通过大量使用try()和invisible()来抑制输出来处理内存问题。对卷曲包来说,这似乎没有任何帮助。
如果有人能帮助我,我有三个相关的问题。
(1)我对内存的利用方式的理解是否因为不必要地交换内存会导致脚本变慢?
(2)curl_fetch_disk应该直接写入磁盘,有没有人知道它为什么要使用这么多内存?
(3)在R中有没有什么好方法可以做到这一点,或者我最好学习一些bash脚本?
使用curl_download的当前方法
getfile_sweep.fun <- function(url
,filename){
invisible(
try(
curl_download(url
,destfile=filename
,quiet=T
)
)
)
}
使用native download.file
的上一个方法getfile_sweep.fun <- function(url
,filename){
invisible(
try(
download.file(url
,destfile=filename
,quiet=T
,method="curl"
)
)
)
}
parLapply loop
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
数据样本 -
url_sweep.df示例: https://www.dropbox.com/s/anldby6tcxjwazc/url_sweep_sample.rds?dl=0
existing.filenames的示例: https://www.dropbox.com/s/0n0phz4h5925qk6/existing_filenames_sample.rds?dl=0
答案 0 :(得分:1)
注意:
1-我没有这么强大的系统,所以我不能重现所提到的每一个问题。
2-所有评论都在这里汇总
3-据说机器已收到升级:EBS to provisioned SSD w/ 6000 IOPs/sec
,但问题仍然存在
可能的问题:
A-如果内存交换开始发生,那么你也不再仅仅使用RAM
了,我认为R
将会越来越难以找到可用的连续内存空间。
与核心数量相比,B-工作负荷和完成工作量所需的时间
c- parallel
设置,fork cluster
可能的解决方案和故障排除:
B-限制内存使用
C-限制核心数
D-如果代码在像个人桌面这样的小型机器上运行良好,那么问题就是如何设置并行使用,或者使用fork cluster。
还要尝试的事情:
A-一般来说parallel
中的overhead
cores
正在运行的作业,现在更多overhead
,您会看到效果更多。当你通过大量花费很少时间的工作时(想想小于第二个),这将导致与不断推动工作相关的core to 8
增加。尝试像您的桌面一样限制Parallelism in R
并尝试使用您的代码?代码运行正常吗?如果是,则在增加程序可用的核心时尝试增加工作量。
从核心数量和ram数量的较低端开始,随着工作量的增加而增加它们,并查看跌落发生的位置。
B-我将发布关于{{1}}的总结,这可能会帮助你抓住我们错过的东西
什么有效: 限制核心数量已经解决了这个问题。正如OP所提到的,他还对代码进行了其他更改,但我无法访问它们。
答案 1 :(得分:0)
您可以改用异步接口。以下简短示例:
from collections import OrderedDict
test = {u'Beta': {
u'SW Engineering': {
u'Resolved': {u'2017-10-06 08:04:15': 1, u'2017-10-15 00:19:35': 3, u'2017-10-11 00:19:29': 2, u'2017-10-09 00:19:00': 1, u'2017-10-14 00:21:09': 3, u'2017-10-12 00:19:52': 3, u'2017-10-08 00:18:58': 1, u'2017-10-10 00:19:31': 2, u'2017-10-13 00:19:28': 3, u'2017-10-07 09:54:33': 1},
u'In Progress': {u'2017-10-06 08:04:15': 9, u'2017-10-15 00:19:35': 12, u'2017-10-11 00:19:29': 11, u'2017-10-09 00:19:00': 9, u'2017-10-14 00:21:09': 12, u'2017-10-12 00:19:52': 11, u'2017-10-08 00:18:58': 9, u'2017-10-10 00:19:31': 10, u'2017-10-13 00:19:28': 11, u'2017-10-07 09:54:33': 9},
u'In Testing': {u'2017-10-06 08:04:15': 7, u'2017-10-15 00:19:35': 7, u'2017-10-11 00:19:29': 7, u'2017-10-09 00:19:00': 7, u'2017-10-14 00:21:09': 7, u'2017-10-12 00:19:52': 7, u'2017-10-08 00:18:58': 7, u'2017-10-10 00:19:31': 7, u'2017-10-13 00:19:28': 7, u'2017-10-07 09:54:33': 7},
u'Reopened': {u'2017-10-06 08:04:15': 1, u'2017-10-15 00:19:35': 1, u'2017-10-11 00:19:29': 1, u'2017-10-09 00:19:00': 1, u'2017-10-14 00:21:09': 1, u'2017-10-12 00:19:52': 1, u'2017-10-08 00:18:58': 1, u'2017-10-10 00:19:31': 1, u'2017-10-13 00:19:28': 1, u'2017-10-07 09:54:33': 1},
u'Closed': {u'2017-10-06 08:04:15': 17, u'2017-10-15 00:19:35': 18, u'2017-10-11 00:19:29': 18, u'2017-10-09 00:19:00': 17, u'2017-10-14 00:21:09': 18, u'2017-10-12 00:19:52': 18, u'2017-10-08 00:18:58': 17, u'2017-10-10 00:19:31': 18, u'2017-10-13 00:19:28': 18, u'2017-10-07 09:54:33': 17},
u'Open': {u'2017-10-06 08:04:15': 5, u'2017-10-15 00:19:35': 8, u'2017-10-11 00:19:29': 8, u'2017-10-09 00:19:00': 5, u'2017-10-14 00:21:09': 8, u'2017-10-12 00:19:52': 7, u'2017-10-08 00:18:58': 5, u'2017-10-10 00:19:31': 8, u'2017-10-13 00:19:28': 8, u'2017-10-07 09:54:33': 5}},
u'SW Engineering33': {
u'Resolved': {u'2017-10-06 08:04:15': 1, u'2017-10-15 00:19:35': 3, u'2017-10-11 00:19:29': 2,
u'2017-10-09 00:19:00': 1, u'2017-10-14 00:21:09': 3, u'2017-10-12 00:19:52': 3,
u'2017-10-08 00:18:58': 1, u'2017-10-10 00:19:31': 2, u'2017-10-13 00:19:28': 3,
u'2017-10-07 09:54:33': 1},
u'Resolved43': {u'2017-10-06 08:04:15': 1, u'2017-10-15 00:19:35': 3, u'2017-10-11 00:19:29': 2,
u'2017-10-09 00:19:00': 1, u'2017-10-14 00:21:09': 3, u'2017-10-12 00:19:52': 3,
u'2017-10-08 00:18:58': 1, u'2017-10-10 00:19:31': 2, u'2017-10-13 00:19:28': 3,
u'2017-10-07 09:54:33': 1},
u'In Progress': {u'2017-10-06 08:04:15': 9, u'2017-10-15 00:19:35': 12, u'2017-10-11 00:19:29': 11,
u'2017-10-09 00:19:00': 9, u'2017-10-14 00:21:09': 12, u'2017-10-12 00:19:52': 11,
u'2017-10-08 00:18:58': 9, u'2017-10-10 00:19:31': 10, u'2017-10-13 00:19:28': 11,
u'2017-10-07 09:54:33': 9},
u'In Testing': {u'2017-10-06 08:04:15': 7, u'2017-10-15 00:19:35': 7, u'2017-10-11 00:19:29': 7,
u'2017-10-09 00:19:00': 7, u'2017-10-14 00:21:09': 7, u'2017-10-12 00:19:52': 7,
u'2017-10-08 00:18:58': 7, u'2017-10-10 00:19:31': 7, u'2017-10-13 00:19:28': 7,
u'2017-10-07 09:54:33': 7},
u'Reopened': {u'2017-10-06 08:04:15': 1, u'2017-10-15 00:19:35': 1, u'2017-10-11 00:19:29': 1,
u'2017-10-09 00:19:00': 1, u'2017-10-14 00:21:09': 1, u'2017-10-12 00:19:52': 1,
u'2017-10-08 00:18:58': 1, u'2017-10-10 00:19:31': 1, u'2017-10-13 00:19:28': 1,
u'2017-10-07 09:54:33': 1},
u'Closed': {u'2017-10-06 08:04:15': 17, u'2017-10-15 00:19:35': 18, u'2017-10-11 00:19:29': 18,
u'2017-10-09 00:19:00': 17, u'2017-10-14 00:21:09': 18, u'2017-10-12 00:19:52': 18,
u'2017-10-08 00:18:58': 17, u'2017-10-10 00:19:31': 18, u'2017-10-13 00:19:28': 18,
u'2017-10-07 09:54:33': 17},
u'Open': {u'2017-10-06 08:04:15': 5, u'2017-10-15 00:19:35': 8, u'2017-10-11 00:19:29': 8,
u'2017-10-09 00:19:00': 5, u'2017-10-14 00:21:09': 8, u'2017-10-12 00:19:52': 7,
u'2017-10-08 00:18:58': 5, u'2017-10-10 00:19:31': 8, u'2017-10-13 00:19:28': 8,
u'2017-10-07 09:54:33': 5}},
u'DSP Engineering': {
u'In Progress': {u'2017-10-15 00:19:35': 1, u'2017-10-14 00:21:09': 1}}}}
capture_len={}
for key,value in test.items():
for key1,value1 in value.items():
for key3,value3 in value1.items():
if key1 not in capture_len:
capture_len[key1]=[value3]
else:
capture_len[key1].append(value3)
for_len={key:len(value) for key,value in capture_len.items()}
sorted_dict=sorted(for_len, key=for_len.get)
ordered_dict=OrderedDict()
for key,value in test.items():
for k in sorted_dict:
for key1,value1 in value.items():
if k==key1:
ordered_dict[k]=value1
final_dict={}
for key,value in ordered_dict.items():
for key2,value2 in test.items():
if key2 not in final_dict:
final_dict[key2]=[(key,value)]
else:
final_dict[key2].append((key,value))
print (final_dict)