Как освободить RAM на web-сервере uwsgi?

Ребятки, нужен совет. Сервер на Ubuntu 18 Digitalocean развернут на flask + nginx + uwsgi. 4 ядра 8 G RAM. Пока единственная операция - выполнение скрипта по обработке переданного через форму изображения. Операция требует большого кол-ва RAM в процессе выполнения. После каждой итерации скрипта катастрофически уменьшается память. Пока после 5-6 выполнений сервак ложится с ошибкой по нехватке памяти. Лог расхода RAM такой (первая запись после рестарта uwsgi и дальше после каждой итерации):

5c76449de9c1d491829167.png

Статус процессов uwsgi и расход памяти процессами
5c76453b0b139304683037.png

Я не совсем понимаю, чем она занята. Скрипт картинку обработал и выдал результат - число, все на этом. Вопрос такой, есть ли способ после выполнения скрипта освобождать за собой RAM?

upd

Загрузка изображений стандартная фласковская, в ней же вызывается скрипт по обработке detect()
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        # if user does not select file, browser also
        # submit a empty part without filename
        if file.filename == '':
            flash('NO selected file')
            return redirect(request.url)
        if not allowed_file(file.filename):
            flash("Only JPG file is used")
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            img = (os.path.join(app.config['UPLOAD_FOLDER'], filename))
            count = detect(images=img)
            return redirect(url_for("result", count=count))
            #return str(count)
    return render_template("index.html")


detect() здесь можно посмотреть https://github.com/ultralytics/yolov3/blob/master/...

pps
Поправка, для чистоты эксперимента запустил скрипт обработки изображения напрямую из командной строки. В момент обработки забирает около 2G RAM. После выполнения операции роста потребления памяти нет вообще, все возвращается к первоначальному значению. Получается, что проблема проявляется после вызова скрипта через фласковскую функцию.
  • Вопрос задан
  • 543 просмотра
Пригласить эксперта
Ответы на вопрос 4
2ord
@2ord
Обработку изображений лучше сделать асинхронной, занося задачу в очередь сообщений.
Обработчик очереди будет работать в отдельном процессе. Если обработка изображения занимает много памяти, то, возможно, можно её сильно оптимизировать.
А что за обработка, если не секрет? Масштабирование? Приведение к единому формату файлов?
Ответ написан
sergey-gornostaev
@sergey-gornostaev Куратор тега uWSGI
Седой и строгий
Без кода ничего конкретного сказать нельзя. Может быть утечка памяти в вашем коде, может утечка в коде библиотечном, а может просто раздувание пулов. Самое простое - переложить операцию обработки изображения на отдельный процесс.
Ответ написан
@Lepilov Автор вопроса
Возможно будет интересно кому то, чем закончилась борьба с памятью.
Так как утечка наблюдалась при работе на локальной машине под родным фласковским сервером, настройки uwsgi отброшены. При вызове напрямую из консоли питоновского файла detect.py все работало четко, значит функция обработки не причем. Поэтому решил послушаться советов и запустить detect.py отдельным потоком используя Redis Queue (RQ).
Заменил в def index()
count = detect(images=img)
return redirect(url_for("result", count=count))

на
job = q.enqueue(detect, img)
            while job.result is None:
                pass
            else:
                count = job.result
                return redirect(url_for("result", count=count))


И завертелось, никакой утечки. Для меня остается загадкой куда девалась память, но результатом я вполне удовлетворен. Плюс немного новых знаний по Redis, RQ, Supervisor поднял для себя)
Ответ написан
saintbyte
@saintbyte
Django developer
Действительно celery / gearmand и можно картинки обрабатывать хоть на дешевом VDS.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы