我正在尝试使用appengine-mapreduce
准备加载到BigQuery中的数据,并且正在运行内存限制。我正在使用CloudStorage,因此this question中可接受的响应可能不适用。
我所看到的是,单个VM实例(似乎是整个映射器任务的协调器)超过了分配给它的~1GB,然后在任何工作人员启动之前被杀死。在此屏幕截图中,有三个实例,只有顶部实例在内存中增长:
在之前的几次尝试中,有多达12个实例,除了一个以外的所有实例都在内存限制之内,只有一个达到极限并被杀死。这告诉我,没有一般的内存泄漏(可能是在Guido van Rossum在早期问题中建议定期调用gc.collect()
),而是在处理和工作的文件的大小和数量之间不匹配关于appengine-mapreduce
代码中文件大小和计数的假设。
在上面的例子中,有12个.zip文件被传递给作业进行处理。最小的.zip文件压缩约12 MB,最大压缩45 MB。以下是我传递给MapperPipeline
的配置:
output = yield mapreduce_pipeline.MapperPipeline(
info.job_name,
info.mapper_function,
'mapreduce.input_readers.FileInputReader',
output_writer_spec='mapreduce.output_writers.FileOutputWriter',
params={
'input_reader': {
'files': gs_paths,
'format': 'zip[lines]',
},
'output_writer': {
'filesystem': 'gs',
'gs_bucket_name': info.results_dirname,
'output_sharding': 'none',
},
},
shards=info.shard_count)
在这种情况下,shard_count
的值为16。
这是熟悉的情况吗?我能做些直截了当的事情来避免达到1GB的内存限制吗? (this question的海报可能没有得到答复,但也遇到了类似的问题。)
答案 0 :(得分:1)
我能够克服第一个障碍,协调员因为内存不足而被杀死,使用大约1-6MB的文件并将碎片计数增加到96个碎片。以下是我之后学到的一些事情:
gc.collect()
,则吞吐量会大幅下降。如果你称它太少,实例就会被杀死。appengine-mapreduce
处理的堆栈部分的HTTP超时,之前工作的开始失败。与内存相关的调优似乎特定于上传的数据量。我感到悲观的是,对于我需要处理的所有不同表格,我们会直截了当地制定一个通用的方法,每个表格都有不同的聚合大小。到目前为止,我能够处理的最多是140 MB压缩(可能是1-2 GB未压缩)。
对于任何尝试此操作的人,以下是我记录的一些数字:
Chunk Shards Total MB MB/shard Time Completed? Total memory Instances Comments
daily 96 83.15 0.87 9:45 Yes ? ?
daily 96 121 1.2 12.35 Yes ? ?
daily 96 140 1.5 8.36 Yes 1200 MB (s. 400 MB) 24
daily 180 236 1.3 - No 1200 MB ?
monthly 32 12 0.38 5:46 Yes Worker killed 4
monthly 110 140 1.3 - No Workers killed 4 Better memory management of workers needed.
monthly 110 140 1.3 - No 8 Memory was better, but throughput became unworkable.
monthly 32 140 4.4 - No Coordinator killed -
monthly 64 140 2.18 - No Workers killed -
daily 180 236 1.3 - No - - HTTP timeouts during startup
daily 96 140 1.5 - No - - HTTP timeouts during startup