Как я могу уменьшить использование памяти моего веб-сервера, который разветвляет процессы для запуска исполняемого файла? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть веб-сервер Django, работающий на экземпляре AWS EC2 с 1 ГБ ОЗУ. Когда на веб-сервер сделан определенный запрос, мне нужно запустить исполняемый файл, используя subprocess.call('./executable'). Исполняемый файл запускает Perl-скрипт, который выполняет некоторые операции ввода-вывода, а затем выполняет некоторые вычисления для данных, проанализированных в файлах. Ничего страшного.

Я начал сталкиваться с проблемами выделения памяти, которые приводили к сбою моего веб-сервера, поэтому я запутался в установке жестких ограничений на виртуальную память, выделенную для каждого подпроцесса с помощью ulimit -v some_value. Я обнаружил, что для каждого подпроцесса требуется около 100 МБ для запуска без ошибок, поэтому неудивительно, что у меня возникают проблемы с памятью только с 1 ГБ ОЗУ.

Мне интересно, однако, почему это использование памяти так высоко. Выделено ли много дополнительной памяти, потому что я звоню subprocess.call из процесса, который работает на веб-сервере, который требует много памяти? Требуется ли запуск исполняемого файла, выполняющего сценарий Perl, с интенсивным использованием памяти, потому что Perl имеет некоторые накладные расходы или что-то в этом роде? Будет ли он использовать гораздо меньше памяти, если скрипт Perl будет переписан на Python и запущен непосредственно на веб-сервере Django?

Буду очень признателен за любую помощь в этом. Спасибо!

1 Ответ

0 голосов
/ 12 сентября 2018

Было несколько замечательных комментариев от людей, более осведомленных о специфике ядер, процессов и памяти, чем я!Проверьте их.

У меня нет однозначного ответа для вас, но я могу надеяться пролить немного света здесь:

Причина использования памяти и, следовательно, выходоб исключении памяти, объяснено в этом SO anwer: Ошибка выделения памяти Python при использовании подпроцесса. Откройте .

, это очень распространенная проблема в Unix, и на самом деле не имеет ничего общегос питоном или биоинформатикой.Вызов os.fork () временно удваивает память родительского процесса (память родительского процесса должна быть доступна дочернему процессу), прежде чем выбросить все это для выполнения exec ().Хотя эта память не всегда на самом деле копируется, система должна иметь достаточно памяти для ее копирования, и, таким образом, если ваш родительский процесс использует более половины системной памяти, и вы выполняете подпроцесс даже "wc -l"msgstr "вы столкнетесь с ошибкой памяти.

Вам следует взглянуть на реализацию этого сценария perl в Python и использование этого модуля / пакета в вашем представлении, избегайте использования другого потока / процесса в вашемцикл запрос-ответ, чтобы справиться с этим.

Еще одна вещь, которая может или не может иметь значение, если это длительное задание или задача с интенсивным использованием процессора, вам следует рассмотреть возможность обработки этого в фоновом режиме, используя что-то вроде Celery или Python RQ .Это позволяет вашему серверу быстро реагировать на запросы и позволяет избежать отставания в запросах, поэтому, чтобы избежать ситуации, когда над 20 запросами все еще работают, потому что эта долго выполняющаяся задача выполняет свою работу и, следовательно, никто другой не может получить доступ к серверу.Выбор использования работников будет зависеть от ваших потребностей, сроков и т. Д.

...