使用 --preload 在 gunicorn 中的工作人员之间共享内存

Posted

技术标签:

【中文标题】使用 --preload 在 gunicorn 中的工作人员之间共享内存【英文标题】:Memory Sharing among workers in gunicorn using --preload 【发布时间】:2017-12-17 17:16:10 【问题描述】:

我有一个大型模型文件,我在 Flask 中构建的 web 服务中使用它,然后通过 Gunicorn 提供服务。文件夹结构是这样的:

A.py
Folder_1\
    __init__.py
    B.py

模型在__init__.py中加载并在B.py中使用 入口点是A.py,其中包含@app.routes, etc.

我从 gunicorn 开始 A.py 并使用 --preload 选项预加载应用程序,并且有 8 个工人

我在 8 个内核上面临 100% 的 CPU 利用率;显然请求被卡住了 在应用程序服务器上并且没有被转发到数据库。 该模型是否也已预加载并可供所有 8 个工作人员使用,即它是否在工作进程之间共享? 如果没有,我必须在 A.py 中加载模型,以便为所有工作人员预加载模型。

我认为模型正在被每个工作进程加载,并且由于模型很大,工作人员被卡在那里。

EDIT 1:由于我被告知这可能是一个重复的问题,我想澄清一下,我并不是在问 python 如何处理共享对象。我知道使用multiprocessing 可以做到这一点。就我而言,我使用 --preload 选项从 gunicorn 启动 8 个工作人员的烧瓶服务器,我的应用程序有 8 个实例正在运行。我的问题是,由于代码是在工人分叉之前预加载的,gunicorn 工人将共享相同的模型对象,或者他们每个人都有一个单独的副本。?

【问题讨论】:

Shared memory in multiprocessing的可能重复 【参考方案1】:

我的问题是,由于代码是在工人分叉之前预加载的,gunicorn 工人将共享相同的模型对象,或者他们每个人都有一个单独的副本。?

这将是一个单独的副本。

预加载只是利用了这样一个事实,即当您调用操作系统的fork() 调用来创建新进程时,操作系统能够在两个进程之间共享未修改的内存部分。通过预加载尽可能多的代码,可以在进程之间共享更多内存。

这只是一个幕后操作系统优化:从每个单独的 python 进程的角度来看,它们拥有每个对象的唯一副本。

【讨论】:

在预加载时保持 mmap MAP_SHARED 的最佳工作人员是什么。事件?

以上是关于使用 --preload 在 gunicorn 中的工作人员之间共享内存的主要内容,如果未能解决你的问题,请参考以下文章

当一些请求被发送时,Gunicorn只启动工作人员

在 heroku 上运行 celery 的最佳实践

如何在 Electron 中正确使用 preload.js

如何将 gdb 与 LD_PRELOAD 一起使用

安装gunicorn

为啥在 gunicorn 上运行的烧瓶应用程序中使用日志轮换时同时在多个文件上写入日志?