【问题标题】:How to store easily python usable read-only data structures in shared memory如何在共享内存中轻松存储python可用的只读数据结构
【发布时间】:2015-04-18 16:14:02
【问题描述】:

我有一个 python 进程作为 WSGI-apache 服务器。我在几台机器上运行着这个过程的许多副本。我的进程中大约有 200 兆字节是只读的 python 数据。我想将这些数据放在内存映射段中,以便进程可以共享这些数据的单个副本。最好的办法是能够附加到这些数据上,这样它们就可以是真正的 python 2.7 数据对象,而不是从 pickle、DBM 或 SQLite 之类的东西中解析出来。

有没有人有示例代码或指向已完成此项目的项目的指针可以分享?

【问题讨论】:

  • "我的进程中大约有 200 兆字节是只读的 python 数据。"我无法理解这部分。你能提供一些细节吗?什么数据类型?你尝试了什么?
  • 您使用的是什么操作系统,您的进程是如何分叉的?如果您使用的是vfork,那么孩子将共享其父母页面的副本,直到它仍然写信给他们。
  • 为什么不使用 Redis 解决您的问题?

标签: python shared-memory wsgi uwsgi


【解决方案1】:

@modelnine 在 StackOverflow 上的This post 为这个问题提供了一个非常全面的答案。正如他所提到的,在您的网络服务器中使用线程而不是进程分叉可以显着减轻这种影响。几年前,我在 CLI Python 进程之间使用了某种类型的共享内存 ran into a similar problem trying to share extremely-large NumPy arrays,最终我们使用了 sharedmem Python 扩展的组合在工作人员之间共享数据(这在某些情况下被证明会泄漏内存,但是,它可能是可以修复的)。只读的mmap() 技术可能对你有用,但我不确定如何在纯python 中做到这一点(NumPy 有一个 memmapping 技术解释了here)。对于这个问题,我从来没有找到任何明确而简单的答案,但希望这可以为您指明一些新的方向。让我们知道你最终做了什么!

【讨论】:

    【解决方案2】:

    很难共享实际的 python 对象,因为它们绑定到进程地址空间。但是,如果您使用mmap,您可以创建非常有用的共享对象。我会创建一个进程来预加载数据,其余的可以使用它。我发现了一篇很好的博客文章,描述了它是如何完成的:http://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/

    【讨论】:

      【解决方案3】:

      由于它是只读数据,因此您无需在进程之间共享任何更新(因为不会有任何更新),我建议您在每个进程中保留一份本地副本。

      如果内存限制是一个问题,您可以查看使用 multiprocessing.Valuemultiprocessing.Array 没有锁:https://docs.python.org/2/library/multiprocessing.html#shared-ctypes-objects

      除了你必须依赖外部进程和一些序列化来完成这件事之外,如果我是你,我会看看 Redis 或 Memcached。

      【讨论】:

        【解决方案4】:

        一种可能性是创建一个 C 或 C++ 扩展,为您的共享数据提供 Pythonic 接口。您可以内存映射 200MB 的原始数据,然后让 C 或 C++ 扩展将其提供给 WSGI 服务。也就是说,您可以在 C 中实现常规(非共享)python 对象,这些对象从共享内存中的某种二进制格式中获取数据。我知道这不是你想要的,但这样数据至少对 WSGI-app 来说是 Python 的。

        但是,如果您的数据包含许多非常小的对象,那么即使“入口点”位于共享内存中也变得很重要(否则它们会浪费太多内存)。也就是说,您必须确保构成数据接口的 PyObject* 指针实际上本身指向共享内存。即,python 对象本身必须在共享内存中。据我可以阅读官方文档,这并不是真正支持的。但是,您总是可以尝试在共享内存中“手工制作”python 对象,看看它是否有效。我猜它会起作用,直到 Python 解释器尝试释放内存。但在你的情况下,它不会,因为它是长期存在的并且是只读的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-26
          • 1970-01-01
          • 2016-12-13
          • 2020-11-16
          • 1970-01-01
          相关资源
          最近更新 更多