会话共享解决多实例登录态
应用从单机扩到多实例后,内存里的 session 不再可靠:同一用户的下一个请求可能落到另一台机器上,登录态就丢了。把会话集中放在 Redis 里,所有实例读同一份数据,登录、续期、退出都变成绩效明确的键操作。会话本身是易失数据,Redis 故障时让用户重新登录即可,不宜把它当作唯一权威状态。
基本信息
| 适用平台 | 任意 Redis 版本;常见于 Web 应用与网关 |
|---|---|
| 数据结构 | Hash 存字段(推荐),或 String 存序列化对象 |
| 续期方式 | 每次请求刷新 EXPIRE,实现滑动过期 |
| 命名建议 | 加环境前缀,如 prod:session:<sid> |
| 反向索引 | uid 到 sid 的 Set,用于强制下线 |
典型使用场景
- 多实例负载均衡下的登录态共享
- 会话集中管理,支持后台强制下线某用户
- 网关鉴权:从 Redis 读取会话校验令牌有效性
- 灰度发布期间新旧版本共享同一份登录状态
- 跨子系统的单点登录态透传
会话读写与续期
会话读写与续期
HSET session:8f2k uid 1001 login_at 1760000000 role admin
EXPIRE session:8f2k 1800 # 首次写入设置 30 分钟过期
HGETALL session:8f2k # 读取会话内容
HGET session:8f2k uid # 只取需要的字段
EXPIRE session:8f2k 1800 # 每次请求续期,滑动过期
DEL session:8f2k # 用户主动退出
# 维护反向索引,支持按用户踢下线
SADD user:1001:sessions 8f2k
SMEMBERS user:1001:sessions设计要点
| 要点 | 做法 | 风险 |
|---|---|---|
| 结构选择 | Hash 存轻量字段 | 整对象序列化会放大每次请求开销 |
| TTL | 滑动续期,或另存绝对过期时间 | 忘记续期导致用户被中途判为未登录 |
| 命名 | 带环境与业务前缀 | 多环境共用实例时键互相覆盖 |
| 踢下线 | uid 到 sid 的反向索引 | 无索引时只能遍历全部会话键 |
| 权威性 | 会话数据必须可重建 | 把唯一状态放会话里,故障后无法恢复 |
会话键只保存校验与展示必需的最小字段:把完整用户档案塞进会话会让每次请求都产生大响应,还容易在字段变更时出现兼容问题。
Redis 故障时会话数据全部失效:必须接受用户重新登录的降级路径,不要让会话成为登录以外业务的唯一数据来源。