3. Redis 基础回顾:数据结构、过期策略与持久化
在构建 SaaS 鉴权拦截链路时,Redis 承担着高速缓存与临时数据存储的核心角色。本章将系统回顾 Redis 的五大常用数据结构、过期策略以及两种持久化机制,为后续集成 JWT 黑名单、会话缓存和令牌刷新奠定基础。
3.1 五大核心数据结构
Redis 提供了丰富的数据结构,在鉴权场景中各有典型用途。下表总结了 String、Hash、Set、ZSet 的特性与适用场景。
| 数据结构 | 内部编码 | 典型命令 | SaaS 鉴权场景 |
|---|---|---|---|
| String | int / embstr / raw | SET / GET / INCR / EXPIRE | 单点登录 Token、API Key、计数器(限流) |
| Hash | ziplist / hashtable | HSET / HGET / HGETALL / HDEL | 用户会话属性(userId、角色、过期时间) |
| Set | intset / hashtable | SADD / SMEMBERS / SISMEMBER / SPOP | JWT 黑名单、权限标签集合 |
| ZSet | ziplist / skiplist | ZADD / ZRANGEBYSCORE / ZREMRANGEBYSCORE | Token 按过期时间排序、自动清理过期条目 |
| List | quicklist | LPUSH / RPOP / LLEN / LTRIM | 操作日志队列、异步消息缓冲 |
实战建议:在 JWT 黑名单场景中,优先使用 Set 存储已注销的 jti(JWT ID),利用 SISMEMBER 实现 O(1) 的快速校验;若需要按过期时间自动淘汰,则改用 ZSet,以过期时间戳作为 score,定期执行 ZREMRANGEBYSCORE 清理。
3.2 过期策略:TTL 与淘汰机制
Redis 的过期策略直接影响缓存命中率与内存安全。SaaS 鉴权链路中,Token 和会话数据必须设置合理的过期时间,防止内存泄漏。
3.2.1 过期时间设置方式
- EXPIRE / PEXPIRE:对已有 Key 设置秒级/毫秒级过期。
- SETEX / PSETEX:写入 String 时同时指定过期时间。
- EXPIREAT / PEXPIREAT:指定未来某个时间戳过期。
# 示例:存储 JWT 黑名单,设置 3600 秒后自动删除
SADD blacklist:jti "abc123"
EXPIRE blacklist:jti 3600
# 使用 SETEX 一步完成
SETEX refresh_token:user_42 86400 "eyJhbGciOiJIUzI1NiJ9..."
3.2.2 三种过期删除策略
| 策略 | 工作方式 | 优点 | 缺点 |
|---|---|---|---|
| 定时删除 | 创建 Key 时启动定时器,到期立即删除 | 内存释放及时 | 大量定时器消耗 CPU |
| 惰性删除 | 访问 Key 时检查是否过期,过期则删除 | CPU 开销低 | 过期 Key 可能长期占用内存 |
| 定期删除 | 每隔 100ms 随机抽查部分 Key,删除过期 Key | CPU 与内存的折中 | 删除频率需调优 |
Redis 实际采用 惰性删除 + 定期删除 的组合策略。当内存达到 maxmemory 上限时,还会触发 内存淘汰策略(如 allkeys-lru、volatile-ttl)。
注意:在 SaaS 鉴权场景中,切勿依赖惰性删除清理 JWT 黑名单。建议使用 ZSet 配合定时任务主动清理过期条目,或为黑名单 Key 设置与 JWT 剩余有效期一致的 TTL,避免黑名单无限膨胀。
3.3 持久化机制:RDB 与 AOF
Redis 作为缓存数据库,持久化决定了数据在重启后的恢复能力。在鉴权链路中,会话和黑名单数据丢失可能导致用户被迫重新登录,因此理解 RDB 和 AOF 的差异至关重要。
3.3.1 RDB(快照持久化)
- 原理:在指定时间间隔内生成内存数据的二进制快照文件(dump.rdb)。
- 触发方式:SAVE(同步阻塞)、BGSAVE(异步 fork 子进程)、自动触发(如
save 900 1)。 - 优点:文件紧凑,恢复速度快,适合备份与灾难恢复。
- 缺点:可能丢失两次快照之间的数据;fork 子进程时可能短暂阻塞。
3.3.2 AOF(追加文件持久化)
- 原理:将每次写命令追加到 AOF 文件末尾,重启时重放命令恢复数据。
- 刷盘策略:
appendfsync always(每次写都刷盘,安全但慢)、everysec(每秒刷盘,推荐)、no(由 OS 决定)。 - 优点:数据安全性高,最多丢失 1 秒数据;支持 AOF 重写压缩文件体积。
- 缺点:文件体积通常大于 RDB;恢复速度较慢。
3.3.3 对比与选型建议
| 维度 | RDB | AOF |
|---|---|---|
| 数据完整性 | 可能丢失较多数据 | 最多丢失 1 秒数据(everysec) |
| 恢复速度 | 快 | 慢(需重放命令) |
| 文件体积 | 紧凑 | 较大(可重写压缩) |
| 对性能影响 | BGSAVE 时 fork 子进程 | 写操作追加文件,always 模式影响较大 |
| 适用场景 | 缓存可丢失、备份恢复 | 数据不能丢失、鉴权会话 |
生产建议:在 SaaS 鉴权场景中,建议同时开启 RDB 和 AOF。RDB 用于快速恢复和备份,AOF 用于保证数据安全。设置
appendfsync everysec 平衡性能与可靠性。对于 JWT 黑名单这类可重建的数据,可适当放宽持久化要求,仅开启 RDB 以节省 I/O 开销。
3.4 数据结构与过期策略关系图
下图展示了 Redis 内部数据结构、过期策略与持久化机制之间的协作关系,帮助理解数据在内存与磁盘之间的流转路径。
3.5 数据结构选型决策流程
在 SaaS 鉴权拦截链路中,选择合适的数据结构直接影响性能与代码复杂度。以下决策流程可帮助快速确定使用哪种 Redis 数据结构。
3.6 本章小结
- String 适合存储单值 Token 和计数器;Hash 管理用户会话的多字段属性;Set 实现 JWT 黑名单;ZSet 按过期时间排序并自动清理。
- Redis 采用 惰性删除 + 定期删除 组合策略,配合 内存淘汰 机制防止 OOM。
- RDB 适合快速备份与恢复,AOF 提供更高数据安全性;生产环境建议两者同时开启。
- 在 SaaS 鉴权链路中,合理选择数据结构和过期策略,能显著提升拦截效率并降低内存消耗。