bigywater.tech
Django · 79

Session 的数据库、缓存、签名 Cookie 存储方式

session 可以放数据库、缓存、文件,甚至客户端 cookie。各自的存放位置、性能、安全边界是什么?这篇把五种后端都搭起来,直接看数据在哪、cookie 里是什么、读写要多久。

可读
signed_cookies 里的数据 base64 一解码就能读,签名只防篡改
4096 字节
cookie 后端存 8000 字符 → 6231 字节,超过浏览器上限会被丢弃
0.83 vs 0.12 ms
db 后端与 cache 后端一次写请求的耗时(本机)

数据在哪里

实测 · 本机执行输出
  [db             ] cookie 值长度 = 32 | django_session 表行数 = 1 | 文件数 = 0 | cookie 内容前 40 字符: z34peyhmzj4soxk66mfcbjn93u46cfm5
  [cache          ] cookie 值长度 = 32 | django_session 表行数 = 0 | 文件数 = 0 | cookie 内容前 40 字符: omiaeze7bb4aramag9t4wdkdxums7ip8
  [cached_db      ] cookie 值长度 = 32 | django_session 表行数 = 1 | 文件数 = 0 | cookie 内容前 40 字符: 5nrfvqhfclp5klo0qel2nusljttw6fbe
  [file           ] cookie 值长度 = 32 | django_session 表行数 = 0 | 文件数 = 1 | cookie 内容前 40 字符: 7awrgo6q49lw11ptt3atzgtepe5erh6r
  [signed_cookies ] cookie 值长度 = 89 | django_session 表行数 = 0 | 文件数 = 0 | cookie 内容前 40 字符: eyJrIjoiYjMxNjFjYTM5YzI5ZWU2MGNmZjYifQ:1

用 SESSION_ENGINE 切换后端。前四种把数据放在服务端,浏览器只拿一个随机 id;signed_cookies 相反,把数据放浏览器里。

signed_cookies 的边界

实测 · 本机执行输出
  不需要密钥就能读出 cookie 里的数据(base64解码): b'{"k":"c21ec1bc98d60d519561"}'
    存 1000 字符 → cookie 长度 816 
    存 3000 字符 → cookie 长度 2343 
    存 5000 字符 → cookie 长度 3900 
    存 8000 字符 → cookie 长度 6231 (超过 4096 浏览器会丢弃)
  篡改签名后读取: {'k': 0} (读到空 session)

用 SECRET_KEY 签名,所以无法伪造;但既不加密,也无法在服务端主动作废(比如「登出所有设备」做不到,第 80 篇的机制是靠密码哈希变化)。

速度

实测 · 本机执行输出
  后端                  读(ms)    写(ms)
  db                  0.263    0.827
  cache               0.092    0.125
  cached_db           0.091    0.606
  file                0.141    0.384
  signed_cookies      0.104    0.152

每次 300 次请求中位数,SQLite 与 LocMem 缓存,没有网络;换成 Redis 缓存 + PostgreSQL,数字会不同(第 98 篇用 Redis 缓存 session)。

分步演示:五种后端

Session 存储后端
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Python 3.14.7 / Django 6.1.1(默认用 SQLite,其它数据库会在文中注明),用 django.test.Client 或真实的本机服务器进程实测;计时用 time.perf_counter,数字每次运行会有小幅抖动。SQLite / LocMemCache / 本机文件;耗时来自 django.test.Client
    • 没有验证:Redis / Memcached 缓存后端、多 worker 下 LocMem 的不一致(文档说法)、session 文件目录的清理、cached_db 缓存被淘汰后的回源、cookie 后端与 SESSION_SERIALIZER 的关系
    京ICP备2026067502号-1京公网安备11010502063487号