Django中请求间对象的存储方式

8 投票
2 回答
6339 浏览
提问于 2025-04-15 13:57

我有一个想法:假设我们有一个用Django写的网页应用,它模拟了一个公告板。这个公告板上有很多讨论串,但其中一些讨论串每小时收到的帖子和浏览量最多。

每个用户看到的讨论串页面稍微有些不同,所以我们不能把整个页面缓存起来,也不能只缓存页面的某些部分。

我的想法是:我在内存中创建一个讨论串的对象结构(包括每个帖子和显示所需的其他数据)。如果有新消息发布,这个结构就会更新,然后每隔X个帖子(或者每隔Y分钟,先到为准),就把新消息写回数据库。如果应用崩溃了,可能会丢失一些帖子,但这对用户和管理员来说都是可以接受的。

我的问题是:我能否创建一个不需要序列化的持久内存存储(也就是说,不用序列化再存到memcached)?我理解WSGI应用(像Django)在请求之间是持续运行的,所以理论上应该是可以的。有没有什么API可以使用?如果没有,有没有其他地方可以查找?

/编辑1:我知道“持久”通常有不同的意思,但在这个情况下,我严格指的是“在请求之间”。

2 个回答

0

内存存储是不持久的,所以不行。

我想你是说你只想在每新增X个对象的帖子后再写入数据库。我猜这是为了提高速度。但是,反正你迟早都得把它们序列化,所以这样其实并没有节省时间。不过,你确实可以通过不把新对象写入磁盘来节省时间,但大多数数据库已经支持这个功能了。

另外,你还提到要缓存渲染后的页面,这属于读取缓存。在这里,你不能缓存最终的结果,但可以缓存数据库查询的结果。这意味着新消息不会立即更新,而是需要等一分钟左右才会显示出来,不过我觉得大多数人会觉得这样是可以接受的。

更新:在这种情况下不行。不过你仍然可以轻松缓存查询结果,但在添加新回复时要使缓存失效。这样应该会有所帮助。

7

在一个生产环境的WSGI中,你可能会有多个工作进程同时处理请求。这些工作进程会不时被重启,这样一来,存储在本地内存中的对象就会丢失。

如果你真的需要保留这些对象(确保你真的需要),我建议你看看Django的缓存框架,特别是本地内存缓存的部分。同时,也可以了解一下会话

不过,即使是本地内存缓存也会使用序列化(通过pickle)。其实可以通过实现一个自定义的缓存后端,轻松地创建一个不需要序列化的本地内存缓存(具体可以参考文档)。你可以使用locmem.py中的代码作为起点,来创建一个不需要序列化的缓存。

不过,我怀疑你是不是有点过早地进行优化了?

撰写回答