Gist
Когда я начинаю использовать копирование при записи, чтобы запустить кучу рабочих wsgi, они сходят с ума и используют тонну ЦП и памяти всякий раз, когда мне нужно перезапустить основной процесс. Это вызывает ошибки OOM, и я хотел бы избежать этого. Я проверил Uwsgi и Gunicorn, и я вижу то же самое поведение.
Проблема
У меня есть веб-приложение с рабочими, требующими большого объема памяти, поэтому я использую --preload
в gunicorn и поведение по умолчанию в uwsgi, поэтому приложение полностью загружается перед разветвлением в порядке включить копирование при записи между процессами - сэкономить на использовании памяти.
Когда я закрываю основной процесс (например, через SIGINT или SIGTERM), все рабочие процессы резко возрастают в загрузке процессора, и моя машина (Ubuntu 16.04, но также тестировавшаяся в Debian 10) теряет огромный кусок доступная память. Это часто вызывает ошибку OOM. Я не вижу какого-либо увеличения RES для каждого из работников, но падение доступной памяти примерно соответствует тому, что я ожидал бы, если бы вся память была полностью скопирована для каждого из работников, прежде чем она немедленно была выделена во время их работы. неисправность. Я хотел бы избежать этого внезапного всплеска использования памяти и в полной мере воспользоваться преимуществами копирования при записи.
Среда тестирования
У меня есть очень простое Flask приложение, которое вы можете использовать для проверки этого:
from flask import Flask
application = Flask(__name__)
my_data = {"data{0}".format(i): "value{0}".format(i) for i in range(2000000)}
@application.route("/")
def index():
return "I have {0} data items totalling {1} characters".format(
len(my_data), sum(len(k) + len(v) for k, v in my_data.items()))
Вы можете запустить приложение с помощью одного из следующих команды:
$ gunicorn --workers=16 --preload app:application
$ uwsgi --http :8080 --processes=16 --wsgi-file app.py
Когда я выполняю ^ C на главном процессе в моем терминале и отслеживаю «свободный» KiB Mem, сообщаемый top, тогда я вижу огромное падение доступной памяти и всплеск в использовании процессора. Обратите внимание, что для каждого работника не сообщается об изменении использования памяти. Есть ли способ безопасно перезапустить uwsgi / gunicorn, чтобы не происходил скачок памяти и процессора?
Шаги для воспроизведения:
- Настройте app.py, как описано выше
- Запустите gunicorn или uwsgi с аргументами, приведенными выше.
- Наблюдать за свободным использованием памяти и процессора (используя top)
- 5,7 ГБ свободно на моей машине до запуска
- 5,3 ГБ свободно на моей машине после запуска
- Ctrl- C в основном процессе gunicorn / uwsgi
- 1,3 ГБ свободно, когда процессы закрываются (и всплески загрузки ЦП)
- 5,7 ГБ свободно после всех процессов фактически отключается (через 2-5 секунд)