使用 Gunicorn 部署时如何在 Flask 方法之间共享内存资源

How to share in memory resources between Flask methods when deploying with Gunicorn

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

基本上需要的是:

据我了解,gunicorn 允许我实现各种挂钩函数,例如在服务器初始化时,flask 请求处理程序方法对 gunicorn 服务器数据结构一无所知。

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

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

您可以使用 preloading.

这将允许您提前创建数据结构,然后分叉每个请求处理进程。这是有效的,因为 写时复制 以及您仅从大型数据结构读取 的知识。

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


这里有一个小片段可以看出预加载的区别。

# 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