Python 在我的gunicorn员工之间共享数据

Python 在我的gunicorn员工之间共享数据,python,gunicorn,spacy,Python,Gunicorn,Spacy,我有一个烧瓶应用程序,由Nginx和Gunicorn与3名工人提供。我的Flask应用程序是一个API微服务,专门用于处理NLP内容,我正在使用spaCy库 我的问题是,他们在加载spaCy管道时占用了大量RAM。load('en')非常占用内存,因为我有3个gunicorn Worker,每个Worker将占用大约400MB的RAM 我的问题是,有没有一种方法可以一次加载管道并在所有gunicorn工作人员之间共享它?一种解决方法是,您可以先加载spaCy管道,然后对结果对象进行pickle(

我有一个烧瓶应用程序,由Nginx和Gunicorn与3名工人提供。我的Flask应用程序是一个API微服务,专门用于处理NLP内容,我正在使用spaCy库

我的问题是,他们在加载spaCy管道时占用了大量RAM。load('en')非常占用内存,因为我有3个gunicorn Worker,每个Worker将占用大约400MB的RAM


我的问题是,有没有一种方法可以一次加载管道并在所有gunicorn工作人员之间共享它?

一种解决方法是,您可以先加载spaCy管道,然后对结果对象进行pickle(或任何舒适的序列化方法)并将其存储在DB或文件系统中。每个工作进程只需获取序列化对象,然后对其进行反序列化。

在工作进程之间共享内存中的管道可能会对您有所帮助

请查收

我想,只要在你的app.py中这样做:

  • 冻结gc
  • 加载管道或将使用大量内存的任何其他资源
  • 解冻gc
  • 以及

    • 确保工作人员不会(直接或间接)修改冻结期间创建的任何对象
    • 将app.py传递给gunicorn
    fork
    发生时,那些包含大量资源的内存页不会被操作系统真正复制,因为您要确保它没有写操作

    如果不冻结gc,内存页仍将被写入,因为gc正在写入对象引用计数。这就是为什么冻结很重要


    我只知道这种方法,但我没有尝试。

    我需要在实例之间共享千兆字节的数据,并使用内存映射文件()。如果每个请求需要从池中检索的数据量很小,那么这就可以了。否则,您可以在找到已装入文件的位置装入ramdisk

    由于我不熟悉SpaCy,我不确定这是否有帮助。我将有一个工人在加载(spacy.load?)时实际处理数据,并将生成的文档(酸洗/编组)写入mmf,其他工人可以从中读取


    要更好地了解mmap,请查看

    也许您可以使用gunicorn的
    preload_app
    。你找到解决方案了吗?@Lee,你在这方面有什么发现吗?你如何使用你的gunicorn工人,即线程或进程?如果进程可以使用redis?顺便问一下,python3.7中首先添加了gc冻结。在模块中对其进行酸洗是否可行?我想在脚本中加载模块,导入它,然后启动worker。如果这样做,工作人员是否会选择导入?当您在脚本中加载模块并导入时,导入功能肯定会工作。但是您仍然会面临内存消耗高的问题,因为每个工作进程都会再次独立地加载它。在启动Flask应用程序之前,您必须单独对其进行pickle,并将序列化文件存储在工作人员可以访问的位置。