把 session 放进 Redis 能提速,但代价是什么?Redis 重启或淘汰了 key,用户会不会被登出?这篇在本机 Redis 上直接看 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)。
[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 表很小、数据库在本机时,数据库后端的开销并不大。