Пик памяти колбы при обработке большого запроса JSON - PullRequest
0 голосов
/ 19 октября 2018

У меня есть приложение фляги (версия фляги 1.0.2), которое обрабатывает документы XML.Документы размещены в формате json, скажем так:

import requests
import sys
import json
with open('big.xml', encoding="utf-8") as f:
    xml_string = f.read()
    print(sys.getsizeof(xml_string) // 1024 // 1024)
    # 283
    gid = "FOO"
    json_data = json.dumps({"file_content": xml_string, "self_id": gid})
    print(sys.getsizeof(json_data) // 1024 // 1024)
    # 305
    result_json = requests.post("http://my_server:8080/api", data=json_data, headers={"Content-Type": "application/json"})

Как видите, xml-файлы могут быть довольно большими, в этом примере около 300 МБ.

Приложение для моих колб,для упрощения это выглядит так:

from flask import Flask, request, jsonify
from memory_profiler import profile

app = Flask(__name__)

@app.route('/api', methods=['POST'])
@profile
def api():
    input_data = request.get_json()
    output_data = {"id": "FOO"}
    response = jsonify(output_data)
    return response

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080, debug=True)

Во время публикации запроса использование памяти приложением колбы увеличивается до ~ 2,8 ГБ .Профилирование памяти в коде выше нигде не близко к этим числам:

Line #    Mem usage    Increment   Line Contents
================================================
     6     27.8 MiB     27.8 MiB   @app.route('/api', methods=['POST'])
     7                             @profile
     8                             def api():
     9    617.3 MiB    589.5 MiB       input_data = request.get_json(request.data)
    10    617.3 MiB      0.0 MiB       output_data = {"id": "FOO"}
    11    617.3 MiB      0.0 MiB       response = jsonify(output_data)
    12    617.3 MiB      0.0 MiB       return response

Чего мне не хватает?Что вызывает этот большой всплеск памяти и как с ним бороться?

1 Ответ

0 голосов
/ 19 октября 2018

Полагаю, вы могли бы сохранить много памяти, если не оборачиваете xml в структуру json и не отправляете дополнительную информацию, например, с помощью заголовков.

функции, такие как get_json и jsonify, удобны,но не оптимизированы для низкого использования памяти .. они, вероятно, копируют данные перед обработкой, поэтому они будут в памяти несколько раз.

я думаю, что вы делаете что-то не так ... функция get_json в колбе имеет следующееподпись: get_json(force=False, silent=False, cache=True) вам не нужно помещать свои данные в нее, потому что вы вызываете функцию в объекте запроса.Кроме того, вы, вероятно, не хотите кэшировать результат в памяти для нескольких вызовов.

try request.get_json(cache=False), и я предполагаю, что использование памяти уменьшится на несколько сотен МБ.

дополнительно я думаюИзвестно, что функции json используют много памяти: https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...