【问题标题】:Caching large objects in a python Flask/Gevent web service在 python Flask/Gevent Web 服务中缓存大对象
【发布时间】:2013-08-19 06:45:23
【问题描述】:

我正在构建一个基于 python 的 Web 服务,它为我们的主应用 API 提供自然语言处理支持。由于它是如此繁重的 NLP,它需要从磁盘中提取一些非常大的 (50-300MB) 语料库文件,然后才能进行任何类型的分析。

如何将这些文件加载​​到内存中,以便它们可用于每个请求?我尝试了 memcached 和 redis,但它们似乎是为更小的对象设计的。我也一直在尝试使用 Flask g 对象,但这只会在一个请求中持续存在。

在使用 gevent(或其他)服务器允许并发连接时,有什么方法可以做到这一点?语料库是完全只读的,因此应该有一种安全的方式将内存暴露给多个 greenlets/threads/processes。

非常感谢,如果这是一个愚蠢的问题,我深表歉意 - 我已经使用 python 工作了很长一段时间,但我对网络编程还比较陌生。

【问题讨论】:

  • IMO 您应该使用与 pickle 不同的存储格式。 ……数据库怎么样?
  • @MarkusUnterwaditzer 是的,我最终选择了 redis。 NLP 的困难在于,对于大多数任务,您需要将整个语料库加载到内存中,通常是某种专门的数据结构。如果您只需要特定任务的语料库,有时可以解决这个问题(就像我最终做的那样),但我不知道有任何数据存储可以支持一般情况。

标签: python caching flask nlp gevent


【解决方案1】:

你不能在服务器实例化时解压文件,然后将解压后的数据保存到全局命名空间中吗?这样,每个请求都可以使用它,并且由于您不打算在其中编写任何内容,因此您不必担心任何竞争条件。

【讨论】:

    【解决方案2】:

    如果您使用 Gevent,您可以在流程的全局范围内拥有只读数据结构,并且它们将由所有 greenlet 共享。使用 Gevent,您的服务器将包含在单个进程中,因此数据可以一次加载并在所有工作程序 greenlet 之间共享。

    封装对数据的访问的一种好方法是将访问函数或类放入模块中。您可以在导入模块时取消选中数据,也可以在有人第一次调用模块中的函数时触发此任务。

    您需要确保不可能引入竞争条件,但如果数据是严格只读的,您应该没问题。

    【讨论】:

    • 谢谢,这就是我要找的。没有意识到我可以使用一个全局命名空间。然而,在找到一种将语料库文件分割成更易消化的块的方法后,我最终选择了 redis 和 Flask-Cache。它超级快,而且现在还可以在不停机的情况下更新语料库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-06
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多