处理大json请求时烧瓶内存峰值

时间:2018-10-19 10:40:44

标签: python memory flask

我有一个烧瓶应用程序(烧瓶版本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 MB。

为简化起见,我的烧瓶应用程序看起来像这样:

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)

在发布请求期间,flask应用程序的内存使用量猛增至〜2.8 GB 。上面代码中的内存配置文件与这些数字相距甚远:

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 :(得分:1)

我想,如果您不将xml封装在json结构中,并使用例如标头发送额外的信息,那么您可以保护大量的内存。

get_jsonjsonify之类的功能很方便,但并未针对低内存使用进行优化。它们可能在处理之前复制数据,因此会多次在内存中存储。

我认为您做错了.. flask中的get_json函数具有以下签名:get_json(force=False, silent=False, cache=True)您不需要将数据放入其中,因为您是在请求对象。另外,您可能不想将结果缓存在内存中以供多次调用。

尝试request.get_json(cache=False),我估计内存使用量将减少几百MB。

另外,我认为json函数使用大量内存:https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/

相关问题