bigywater.tech
Django · 98

使用 Redis 缓存 Session

把 session 放进 Redis 能提速,但代价是什么?Redis 重启或淘汰了 key,用户会不会被登出?这篇在本机 Redis 上直接看 session 的存储形态,并做「清空」和「内存淘汰」两个破坏性实验(用的是本次实验自己起的 Redis,没有碰任何其它实例)。

1209600 秒
Redis 里 session key 的 TTL = SESSION_COOKIE_AGE(14 天)
全员登出
cache 会话后端 + Redis 被清空或淘汰 key 时,对应用户登出;cached_db 后端回源数据库不受影响
allkeys-lru
Redis 的淘汰策略不区分 session 与其它缓存,内存吃紧时 session 一起被淘汰

session 在 Redis 里的样子

实测 · 本机执行输出
  Redis 里的 key: [':1:django.contrib.sessions.cachenunz0m61qq2thmdb0z2lnl4c1iyrxiqe']
  TTL = 1209600 秒(SESSION_COOKIE_AGE 默认 1209600 = 14 天)
  值的前 40 字节: b'\x80\x05\x95\xaf\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\r_auth_user_id\x94\x8c\x011\x94\x8c\x12_aut' (pickle 序列化的字典)

本实验用的是 Django 6.1 自带的 RedisCache(需要 redis 客户端库),序列化用 pickle。要在 redis-cli 里找 session,用 KEYS *django.contrib.sessions*(生产环境别用 KEYS,用 SCAN)。

Redis 丢数据时

实测 · 本机执行输出
  [cache(Redis)]  Redis 被 FLUSHALL 之后: {'user': 'AnonymousUser'}
  [cached_db(Redis+DB)]  Redis 被 FLUSHALL 之后: {'user': 'u'}
  [db]  Redis 被 FLUSHALL 之后: {'user': 'u'}

选择 cache 后端就等于把「登录状态」当作可丢的缓存。可以接受的场景(登出后重新登录成本低)才用;否则用 cached_db。

内存淘汰

实测 · 本机执行输出
  [cache(Redis)]
    登录后: u
    用 3 MB 的其它 key 挤满 maxmemory=2mb 之后,Redis key 数: 836  该会话在 Redis 里: False
    之后再访问: {'user': 'AnonymousUser'}
  [cached_db(Redis+DB)]
    登录后: u
    用 3 MB 的其它 key 挤满 maxmemory=2mb 之后,Redis key 数: 819  该会话在 Redis 里: False
    之后再访问: {'user': 'u'}

同一个 Redis 既存页面缓存又存 session 时,页面缓存把内存挤满会淘汰 session。把 session 放到单独的 Redis(或 db),并且给它设 noeviction 之类的策略(本文没有测)。

性能

实测 · 本机执行输出
  cache(Redis)           0.407 ms
  cached_db(Redis+DB)    0.410 ms
  db                     0.399 ms

本机数字没有区别,不能据此说「Redis 不快」——只说明当 session 表很小、数据库在本机时,数据库后端的开销并不大。

分步演示:Redis 里的 session

Redis 缓存 Session
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Python 3.14.7 / Django 6.1.1(默认用 SQLite,其它数据库会在文中注明),用 django.test.Client 或真实的本机服务器进程实测;计时用 time.perf_counter,数字每次运行会有小幅抖动。Redis 8.10.2 本机临时实例(端口 9463),FLUSHALL 与 maxmemory 只作用在这个实例上
    • 没有验证:Redis 持久化(AOF / RDB)对 session 的保护、Sentinel / Cluster 下的 session、django-redis 库的行为、session 序列化器选择(JSON)、高并发下的延迟
    京ICP备2026067502号-1京公网安备11010502063487号