如何在共享内存中轻松存储python可用的只读数据结构

如何在共享内存中轻松存储python可用的只读数据结构,python,shared-memory,wsgi,uwsgi,Python,Shared Memory,Wsgi,Uwsgi,我有一个python进程作为WSGI apache服务器。我在每台机器上都有许多这个过程的副本。我的进程大约有200兆字节是只读python数据。我希望将这些数据放在内存映射段中,以便进程可以共享这些数据的单个副本。最好是能够附加到这些数据,使它们成为实际的Python2.7数据对象,而不是用pickle、DBM或SQLite之类的东西来解析它们 是否有人拥有指向已完成此操作的项目的示例代码或指针以共享?由于它是只读数据,您不需要在进程之间共享任何更新(因为不会有任何更新),我建议您在每个进程中

我有一个python进程作为WSGI apache服务器。我在每台机器上都有许多这个过程的副本。我的进程大约有200兆字节是只读python数据。我希望将这些数据放在内存映射段中,以便进程可以共享这些数据的单个副本。最好是能够附加到这些数据,使它们成为实际的Python2.7数据对象,而不是用pickle、DBM或SQLite之类的东西来解析它们


是否有人拥有指向已完成此操作的项目的示例代码或指针以共享?

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

如果内存限制是一个问题,您可以使用不带锁的
多处理.Value
多处理.Array
来查看:


除此之外,你必须依靠外部进程和一些序列化来完成这项工作,如果我是你,我会看看Redis或Memcached。

by@modelnine on StackOverflow为这个问题提供了一个非常全面的答案。正如他所提到的,在您的Web服务器中使用线程而不是进程分叉可以显著地感受到这一点的影响。几年前,我在CLI Python进程之间使用了某种类型的共享内存,最终我们使用了Python扩展的组合来在工作人员之间共享数据(这在某些情况下被证明会泄漏内存,但可能是可以修复的)。只读
mmap()
技术可能适合您,但我不确定在纯python中如何做到这一点(NumPy解释了memmapping技术)。对于这个问题,我从来没有找到任何清晰简单的答案,但希望这能为你指明一些新的方向。让我们知道你最终会做什么

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


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

很难共享实际的python对象,因为它们绑定到进程地址空间。但是,如果使用
mmap
,则可以创建非常有用的共享对象。我将创建一个进程来预加载数据,其他进程可以使用它。我发现了一篇很好的博客文章,描述了如何做到这一点:

“我的进程大约有200兆字节是只读的python数据。”我不理解这一部分。你能提供一些细节吗?什么数据类型?您尝试了什么?您使用的是什么操作系统?您的流程如何分叉?如果您使用的是
vWork
,那么孩子将共享其父母页面的一个副本,直到它写入父母页面为止。为什么使用Redis不能解决您的问题?