bigywater.tech
Django · 93

LocMem、Database、File-Based、Redis 缓存对比

LocMem、数据库、文件、Redis 四种缓存后端到底差在哪?多进程下能共享吗?重启后还在吗?这篇在本机把它们并排跑一遍,包括真实的 gunicorn 双 worker 场景。

11/20
gunicorn 2 个 worker 下 LocMem 的命中(每个 worker 一份缓存);其它后端 20/20
2.6 vs 90 µs
LocMem 与 Redis 一次 get 命中的耗时(本机回环)
300
LocMem 默认 MAX_ENTRIES:写 500 个只剩 300 个

速度

实测 · 本机执行输出
  后端          set(µs)     get 命中(µs)     get 未命中(µs)
  locmem          3.1            2.6             2.7
  db            349.6           26.2            25.1
  file          399.6            7.7             7.1
  redis          99.4           90.2            89.6

只是一次调用的延迟。Redis 的价值不在单次快,而在「多进程共享、可以独立扩容、支持过期与内存上限」。

进程间共享

实测 · 本机执行输出
  locmem   set 由 pid 39940 执行;20 次读取来自 2 个 worker,读到该值 11/20 次
  db       set 由 pid 39956 执行;20 次读取来自 2 个 worker,读到该值 20/20 次
  file     set 由 pid 40059 执行;20 次读取来自 2 个 worker,读到该值 20/20 次
  redis    set 由 pid 40068 执行;20 次读取来自 2 个 worker,读到该值 20/20 次

这是 LocMem 最大的坑:开发时单进程一切正常,上线用 gunicorn 多 worker 后缓存表现「不稳定」。缓存失效只发生在当前 worker,别的 worker 继续返回旧值。

重启

实测 · 本机执行输出
  locmem   重启后 get = None (丢失)
  db       重启后 get = 40104 (保留)
  file     重启后 get = 40131 (保留)
  redis    重启后 get = 40144 (保留)

持久性只对「缓存后端本身」有意义:Django 进程重启,共享后端里的缓存仍在。

LocMem 的容量

实测 · 本机执行输出
  写入 500 个 key 后还在的: 300 (MAX_ENTRIES 默认 300,超过后淘汰约 1/3)
  最早写入的 k0 还在吗: None  最新的 k499: 499

可以用 OPTIONS: {MAX_ENTRIES: ..., CULL_FREQUENCY: ...} 调整(本文没有测调整后的结果)。

分步演示:四种后端

缓存后端对比
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Python 3.14.7 / Django 6.1.1(默认用 SQLite,其它数据库会在文中注明),用 django.test.Client 或真实的本机服务器进程实测;计时用 time.perf_counter,数字每次运行会有小幅抖动。Redis 8.10.2 本机临时实例(端口 9460);gunicorn 26.2,2 worker;耗时为 1000 次中位数
    • 没有验证:Memcached 后端、跨机器网络下的 Redis 延迟、Redis 缓存的内存上限与淘汰策略(第 98 篇部分涉及)、django-redis 等第三方后端、db 缓存表的清理
    京ICP备2026067502号-1京公网安备11010502063487号