根据数据结构的类型,您可以尝试使用内存映射文件。有一个Python library 封装了相关的系统调用。
文件的结构需要反映您正在使用的数据结构。例如,如果您需要一个 trie,您可以将所有字符串存储在一个排序列表中,然后对前缀进行二进制搜索以查看哪些字符串具有该前缀。
当您访问文件中的页面时,它们将通过操作系统的磁盘读取缓存加载到内存中。对同一页面的后续请求将很快。因为磁盘缓存可以在进程之间共享,所有 UWSGI 工作人员都将受益于访问缓存页面的速度。
我在 Linux 上尝试了这个,强制它在两个单独的进程中扫描一个大文件。创建一个名为“big”的大文件,然后在两个单独的 Python 进程中运行以下命令:
import mmap
with open('big') as fp:
map = mmap.mmap(fp.fileno(), 0, mmap.MAP_PRIVATE)
if x == 'a': # Make sure 'a' doesn't occur in the file!
break
您会注意到两个进程的常驻内存在扫描文件时会增加,但是共享内存使用量也会增加。例如,如果big 是一个 1 GB 的文件,则两个进程似乎都在使用大约 1 GB 的内存。但是,系统上的整体内存负载只会增加 1 GB,而不是 2 GB。
显然,这种方法存在一些限制,主要是您要共享的数据结构很容易以二进制格式表示。此外,每当您访问它们时,Python 都需要将文件中的任何字节复制到内存中。如果您经常以小块的形式读取整个文件,这可能会导致积极的垃圾收集,或者如果您读取大块,则会破坏内存映射的共享内存优势。