在与Gunicorn一起部署时,如何在Flask方法之间共享内存资源

时间:2017-02-24 13:14:14

标签: python flask multiprocessing gunicorn

我使用Flask实现了一个简单的微服务,其中处理请求的方法根据请求数据和加载到内存中的相当大的数据结构计算响应。 现在,当我使用gunicorn和大量工作线程部署此应用程序时,我只想在所有工作者的请求处理程序之间共享数据结构。由于只读取数据,因此不需要锁定或类似。这样做的最佳方式是什么?

基本上需要的是:

  • 在初始化服务器时加载/创建大型数据结构
  • 以某种方式获取请求处理方法中的句柄以访问数据结构

据我所知,gunicorn允许我实现各种钩子功能,例如对于服务器初始化的时间,但是烧瓶请求处理程序方法对gunicorn服务器数据结构一无所知。

我不想为此使用redis或数据库系统之类的东西,因为所有数据都在需要加载到内存中的数据结构中,并且不必涉及反序列化。

对使用大数据结构的每个请求执行的计算可能很长,因此必须在每个请求的真正独立的线程或进程中同时发生(这应该通过在多核计算机上运行来扩展)。

1 个答案:

答案 0 :(得分:7)

您可以使用preloading

这将允许您提前创建数据结构,然后分叉每个请求处理过程。这是因为 copy-on-write 以及您只是从大型数据结构中读取的知识。

注意:虽然这样可行,但它应该只适用于非常小的应用程序或开发环境。我认为更加生产友好的方式是将这些计算排队作为后端的任务,因为它们将长期运行。然后,您可以通知用户已完成的状态。

这是一个小片段,可以看到预加载的区别。

# app.py

import flask

app = flask.Flask(__name__)

def load_data():
    print('calculating some stuff')
    return {'big': 'data'}

@app.route('/')
def index():
    return repr(data)

data = load_data()

使用gunicorn app:app --workers 2

运行
[2017-02-24 09:01:01 -0500] [38392] [INFO] Starting gunicorn 19.6.0
[2017-02-24 09:01:01 -0500] [38392] [INFO] Listening at: http://127.0.0.1:8000 (38392)
[2017-02-24 09:01:01 -0500] [38392] [INFO] Using worker: sync
[2017-02-24 09:01:01 -0500] [38395] [INFO] Booting worker with pid: 38395
[2017-02-24 09:01:01 -0500] [38396] [INFO] Booting worker with pid: 38396
calculating some stuff
calculating some stuff

使用gunicorn app:app --workers 2 --preload

运行
calculating some stuff
[2017-02-24 09:01:06 -0500] [38403] [INFO] Starting gunicorn 19.6.0
[2017-02-24 09:01:06 -0500] [38403] [INFO] Listening at: http://127.0.0.1:8000 (38403)
[2017-02-24 09:01:06 -0500] [38403] [INFO] Using worker: sync
[2017-02-24 09:01:06 -0500] [38406] [INFO] Booting worker with pid: 38406
[2017-02-24 09:01:06 -0500] [38407] [INFO] Booting worker with pid: 38407