我怀疑这是可能的,但这是问题和建议的解决方案(提出的解决方案的可行性是这个问题的对象):
我有一些“全局数据”需要可用于所有请求.我将这些数据保存到Riak并使用Redis作为访问速度的缓存层(现在……).数据被分成大约30个逻辑块,每个块大约为8 KB.
每个请求都需要读取这8KB块中的4个,从而从Redis或Riak读入32KB数据.这是对任何特定于请求的数据的补充,这些数据也需要被读取(这是相当多的).
假设每秒甚至3000个请求(这不是一个真实的服务器,所以我没有实数,但3000ps是一个合理的假设,可能更多),这意味着从Addis或者Riak的ADDITION转移到已经没有的96KBps – 从应用程序逻辑中发出的重要其他调用.此外,Python每秒3000次解析这些8KB对象的JSON.
所有这一切 – 特别是Python不得不反复反序列化数据 – 似乎是一种彻头彻尾的浪费,一个非常优雅的解决方案就是将反序列化数据缓存在Python中的内存中本机对象中,我可以定期刷新和当所有这些“静态”数据变得陈旧时.在几分钟(或几小时)内,而不是每秒3000次.
但我不知道这是否可能.您实际上需要一个“始终运行”的应用程序来缓存其内存中的任何数据.而且我知道在Nginx uwsgi python组合中并不是这种情况(与节点之类的东西相比) – 除非我非常错误,否则python内存数据不会持久存储在我所知的所有请求中.
不幸的是,这是一个我“继承”的系统,因此不能在基础技术方面做太多改变,也不足以了解Nginx uwsgi python组合如何在启动Python进程和持久化Python方面发挥作用 – 记忆数据 – 这意味着我可能会因为上面的假设而非常错误!
因此,直接建议这个解决方案是否有效,可以帮助我理解Nginx uwsgi python如何在启动新进程和内存分配方面起作用,这将有很大帮助.
P.S:
>已经查看了Nginx,uwsgi等的一些文档,但还没有完全理解我的用例的后果.希望现在在这方面取得一些进展
>如果内存中的东西可以解决,我会扔掉Redis,因为我只缓存上面提到的静态数据.这使得进程内持久性内存中的Python缓存对我来说更具吸引力,减少了系统中的一个移动部分,并且每个请求至少减少了四次网络往返.
通常,您需要一个级别的键值存储.有时,为值提供固定大小的缓冲区(您可以直接使用它作为str / bytes / bytearray对象;您需要在那里构建其他任何内容或以其他方式序列化),这就是您所需要的.在这种情况下,uWSGI的内置caching framework将照顾您需要的一切.
如果您需要更精确的控制,您可以查看如何在SharedArea
之上实现缓存并执行自定义操作.但是,我不建议这样做.它基本上为您提供了与文件相同的API,而且仅使用文件的唯一真正优势是服务器将管理文件的生命周期;它适用于所有支持uWSGI的语言,甚至是那些不允许文件的语言;如果您以后需要,它可以更轻松地将您的自定义缓存迁移到分布式(多台计算机)缓存.我认为这些都与你无关.
获得平坦键值存储但没有固定大小缓冲区的另一种方法是使用Python的stdlib anydbm
.键值查找与pythonic一样:它看起来就像一个dict,除了它备份到一个磁盘上的BDB(或类似)数据库,在内存中适当缓存,而不是存储在内存中的哈希表中.
如果你需要处理一些其他简单的类型 – 任何对于un / pickle来说非常快速的东西,比如整数 – 你可能想要考虑shelve
.
如果您的结构足够严格,则可以将键值数据库用于顶级,但可以通过ctypes.Structure访问值,或使用struct进行de / serialize.但通常情况下,如果你能做到这一点,你也可以消除顶层,此时你的整个东西只是一个大的结构或数组.
此时,您可以使用普通文件进行存储 – mmap(对于ctypes),或者只是打开并读取它(对于struct).
或者使用多处理的Shared ctypes
Objects直接从共享内存区域访问您的Structure.
同时,如果你实际上并不是一直需要所有的缓存数据,而是每隔一段时间只需要一点点,这正是数据库的用途.同样,anydbm等可能就是您所需要的,但如果您有复杂的结构,请绘制ER图,将其转换为一组表,并使用类似MysqL的东西.