多处理:分叉的缺点?

时间:2017-01-19 15:15:45

标签: python multithreading multiprocessing celery

我们遇到了Python Celery(使用多处理)的问题,其中大型周期性(计划)任务在短时间内消耗大量内存,但因为工作进程在池的生命周期中存在({{1内存不是垃圾收集的(即它正在"高水位"保留)。

(Heroku进一步恶化了这个问题,Heroku看到分配了大量恒定的内存并将其转换为交换,从而降低了性能。)

我们发现通过设置MAX_TASKS_PER_CHILD=None,我们在每个任务之后分叉一个新进程(Celery worker实例),并且内存被正确地垃圾收集。甜!

然而,有很多文章提出相同的解决方案,但我没有发现任何缺点。 在每项任务之后分配新流程的潜在缺点是什么?

我的猜测是:
1. CPU开销(但可能是微小数量)
2.分叉时可能出现的错误(但我无法找到相关文件)

1 个答案:

答案 0 :(得分:2)

除了重复分叉的CPU开销明显增加(如果工作人员为每个任务完成足够的工作,这并不是什么大问题),如果父进程的规模继续扩大,那么可能存在一个缺点。如果是这样,它会增加所有子进程的大小(这会牺牲越来越大的父进程)。这并不重要(可能很少写入内存,因此需要很少的复制,实际的内存使用不会成为主要问题),但IIRC,Linux overcomcom heuristics假设COW内存最终会被复制,即使您在实际附近超出私有页面的启发式限制,也可以调用OOM杀手。

在Python 3.4及更高版本中,您可以通过在程序启动时明确setting your multiprocessing start method to forkserver来避免此问题(在执行工作人员不依赖的任何工作之前),这将从单独的服务器进程分叉工作人员不应该大幅度增加。