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 内部数据结构、过期策略与持久化机制之间的协作关系,帮助理解数据在内存与磁盘之间的流转路径。

Redis 数据结构、过期策略与持久化协作图 客户端 命令处理器 内存数据结构 String Hash Set ZSet List 过期策略 惰性删除 定期删除 内存淘汰 持久化机制 RDB 快照 AOF 追加 磁盘(dump.rdb / appendonly.aof) 说明:客户端写入数据 → 命令处理器选择数据结构存储 → 过期策略自动清理 → 持久化机制将数据写入磁盘

3.5 数据结构选型决策流程

在 SaaS 鉴权拦截链路中,选择合适的数据结构直接影响性能与代码复杂度。以下决策流程可帮助快速确定使用哪种 Redis 数据结构。

SaaS 鉴权场景 Redis 数据结构选型决策 需要存储什么数据? 单个值(Token/Key) 多个字段(会话属性) 集合(黑名单/权限) 使用 String 使用 Hash 需要排序? 是 → 使用 ZSet 否 → 使用 Set 提示:JWT 黑名单用 Set(无需排序),Token 过期队列用 ZSet(按 score 排序),用户会话用 Hash

3.6 本章小结

  • String 适合存储单值 Token 和计数器;Hash 管理用户会话的多字段属性;Set 实现 JWT 黑名单;ZSet 按过期时间排序并自动清理。
  • Redis 采用 惰性删除 + 定期删除 组合策略,配合 内存淘汰 机制防止 OOM。
  • RDB 适合快速备份与恢复,AOF 提供更高数据安全性;生产环境建议两者同时开启。
  • 在 SaaS 鉴权链路中,合理选择数据结构和过期策略,能显著提升拦截效率并降低内存消耗。