必须用 setex 或 set 加 ex 选项,因 session 需明确过期时间;key 必须带 session: 前缀并区分环境与服务;连接失败需校验返回值防静默丢数据;cluster 下 key 需用 hash tag 如 session:{web}:abc123。

Redis 作为 Session 存储时,SET 和 SETEX 用哪个?
必须用 SETEX(或 SET 加 EX 选项),不能只用 SET。Session 有明确过期时间,而 SET 默认永不过期,一旦漏设 TTL,就会堆积无效 session,拖慢 KEYS 扫描、影响内存回收,甚至触发 Redis 内存淘汰误删活跃 session。
实操建议:
-
SETEX session:abc123 1800 {"uid":1001,"login_at":1715234567}—— 简洁可靠,原子写入+过期 - 新版 Redis 推荐用
SET session:abc123 '{"uid":1001}' EX 1800,语义更清晰,且支持 NX/XX 等条件写入 - 避免在应用层先
SET再EXPIRE:非原子操作,中间崩溃会导致 key 永久存在
Session key 的命名必须带前缀吗?
必须。不加前缀的 abc123 这类裸 key,和业务缓存、临时队列混在一起,后续无法批量清理、无法设置不同过期策略、监控也分不清来源。
实操建议:
- 统一用
session:前缀,如session:web:abc123或session:api:xyz789 - 多服务共用 Redis 时,前缀要区分环境与服务,例如
session:prod:order:...,避免测试 session 污染生产 - 别用用户 ID 直接当 key(如
session:1001):同一用户多端登录会产生冲突,应使用随机生成的 session ID
Redis 连接断了,Session 写入失败会静默丢数据吗?
会,而且非常危险。多数客户端默认不抛异常,只是返回 false 或 null,如果上层没检查返回值,就以为 session 已保存成功,用户下一秒刷新就登出。
实操建议:
- 所有
SETEX/GET调用后,必须判断返回值是否符合预期(比如True或非空字符串),否则立即拒绝请求或跳转登录页 - 连接池配置里打开
socket_timeout和retry_on_timeout(如 redis-py 的socket_keepalive=True),但别依赖重试——Session 写入必须幂等,重试可能造成重复登录记录 - 上线前用
redis-cli -p 6379 shutdown save模拟 Redis 不可用,验证错误路径是否兜得住
用 Redis Cluster 存 Session,要注意哪些坑?
Cluster 对 key 做哈希分片,而 session key 如果含 {...} 大括号以外的动态内容(比如 session:user_1001:abc123),会导致同一个用户的多次请求落到不同节点,出现“有时登录有时掉线”这种玄学问题。
实操建议:
- key 必须把 hash tag 写死,例如
session:{web}:abc123或session:{api}:xyz789,确保所有 session key 落在同一 slot - 不要用
HASH结构存单个 session(如HSET session:abc123 uid 1001 login_at 1715234567):Cluster 下HGETALL不支持跨节点执行,会报CROSSSLOT错误 - 如果已用 Hash,改用
JSON.SET(需 Redis 7.0+)或坚持用SET存 JSON 字符串——简单、兼容、可跨集群
真正麻烦的不是怎么存,而是 session 有效期和前端 cookie Max-Age 是否对齐、refresh token 是否同步更新、以及用户主动登出时有没有调用 DEL session:xxx。这些环节漏一个,分布式 session 就会开始“假装在线”。










