2017-01-19 3 views
1

Мы сталкиваемся с проблемой с Pineton Celery (который использует многопроцессорность), где большие периодические (запланированные) задачи потребляют огромное количество памяти для коротких всплесков времени, но поскольку рабочий процесс живет в течение всего жизненного цикла пула (MAX_TASKS_PER_CHILD=None), память не является сборкой мусора (то есть, она является «высокой водой»).Многопроцессорность: нижняя часть вилки?

(Эта проблема еще больше усугубляется Heroku, который видит большую, постоянное количество выделенной памяти и превращает его в своп, что снижает производительность.)

Мы обнаружили, что, установив MAX_TASKS_PER_CHILD=1, мы раскошелиться новый процесс (экземпляр работника сельдерея) после каждой задачи, а память - правильно собранный мусор. Милая!

Однако есть много статей, которые предлагают одно и то же решение, но я не определил никаких недостатков. Каковы потенциальные недостатки в открытии нового процесса после каждой задачи?

Моих догадки будут:
1. накладные расходы CPU (но, вероятно, крошечных количество)
2. Потенциальные ошибки при разветвлении (но я не могу найти никакой документации по этому вопросу)

ответ

2

Помимо от очевидного увеличения накладных расходов ЦП от повторного форсинга (неважно, если работники выполняют достаточную работу на одну задачу), одним из возможных недостатков было бы, если родительский процесс продолжает расти в размере. Если это так, он увеличивает размер всех дочерних процессов (которые разворачивают больший и больший родитель). Это не имеет большого значения (предположительно, мало памяти будет записано, и поэтому требуется небольшое копирование, а фактическое использование памяти не будет серьезной проблемой), но IIRC, Linux overcommit эвристики предполагают, что память COW в конечном итоге копировать, и вы могли бы вызвать убийцу OOM, даже если вы нигде не находились рядом с фактически, превышающим эвристический предел с точки зрения частных страниц.

На Python 3.4 и выше вы можете избежать этой проблемы, явно указав setting your multiprocessing start method to forkserver на запуск программы (прежде чем выполнять какую-либо работу, на которую не полагаются работники), что приведет к тому, что работники будут работать с отдельным сервером, что не должно резко увеличиваться размер.

Смежные вопросы