Redis 基础回顾:核心数据结构、持久化机制及高可用方案

在深入缓存与 OIDC 集成之前,必须夯实 Redis 基础。本章聚焦三大支柱:核心数据结构(决定缓存建模方式)、持久化机制(保障数据不丢失)、高可用方案(确保服务连续性)。理解这些是后续架构调优的前提。

2.1 核心数据结构

Redis 提供了 5 种基本数据结构及 3 种高级结构,每种都有独特的应用场景。下表总结了它们的特性与典型用途:

数据结构 底层编码 时间复杂度(关键操作) 典型场景
String int / embstr / raw GET/SET: O(1) 缓存对象、计数器、分布式锁
Hash ziplist / hashtable HGET/HSET: O(1) 对象字段存储、用户属性
List quicklist LPUSH/RPOP: O(1) 消息队列、时间线、最新列表
Set intset / hashtable SADD/SISMEMBER: O(1) 标签系统、去重、共同好友
Sorted Set ziplist / skiplist ZADD: O(log N) 排行榜、延迟队列、限流窗口
Bitmap String 扩展 GETBIT/SETBIT: O(1) 签到统计、布隆过滤器
HyperLogLog 稀疏/密集编码 PFADD: O(1) UV 统计、基数估算
Stream listpack / rax XADD: O(1) 消息队列、事件溯源、日志
架构建议: 在 OIDC 会话缓存场景中,Hash 用于存储用户属性(避免序列化开销),String 用于 access_token 与 refresh_token 的键值对,Sorted Set 用于令牌过期时间的自动排序与清理。

2.2 持久化机制:RDB 与 AOF

Redis 提供两种持久化方式,各有优劣。生产环境通常采用 RDB + AOF 混合模式。

2.2.1 RDB(快照)

  • 原理: 通过 fork 子进程,将内存数据全量写入临时 RDB 文件,替换旧文件。
  • 触发方式: save(阻塞)、bgsave(异步)、配置自动触发(如 save 900 1)。
  • 优点: 文件紧凑,适合备份与灾难恢复;恢复速度极快。
  • 缺点: 可能丢失两次快照间的数据;fork 时若内存过大,可能造成短暂卡顿。

2.2.2 AOF(追加文件)

  • 原理: 将每次写命令追加到 AOF 文件末尾,通过重写机制压缩体积。
  • 刷盘策略:
    • always:每次写入都 fsync,最安全但最慢。
    • everysec:每秒 fsync,性能与安全的平衡点(推荐)。
    • no:由操作系统决定,性能最高但丢失风险大。
  • 优点: 数据丢失少(最多 1 秒数据);文件可读,便于误操作恢复。
  • 缺点: 文件体积通常大于 RDB;恢复速度较慢。

2.2.3 混合持久化(Redis 4.0+)

在 AOF 重写时,将当前内存数据以 RDB 格式写入 AOF 文件头部,后续增量命令继续以 AOF 格式追加。兼顾 RDB 的快速恢复与 AOF 的低丢失率。

配置示例(redis.conf):
# 开启混合持久化
aof-use-rdb-preamble yes

# RDB 配置
save 900 1
save 300 10
save 60 10000

# AOF 配置
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
Redis 持久化机制对比 RDB 快照 fork 子进程 全量写入磁盘 恢复极快 AOF 追加 写命令追加 everysec fsync 丢失 ≤1s 数据 混合持久化 RDB 头 + AOF 尾 重写时生成 快速 + 安全 生产推荐:混合持久化(aof-use-rdb-preamble yes)+ appendfsync everysec

2.3 高可用方案

Redis 高可用经历了从主从复制到哨兵再到集群的演进。三种方案各有侧重,适用于不同规模与可靠性要求的场景。

2.3.1 主从复制

  • 架构: 一个 Master 节点,多个 Slave 节点。Master 负责写,Slave 负责读。
  • 同步方式: 全量同步(RDB 文件传输)+ 增量同步(命令传播)。
  • 局限: Master 宕机后需要手动切换,无法自动故障转移。

2.3.2 哨兵模式

  • 核心组件: Sentinel 集群(至少 3 个节点)监控 Master 与 Slave。
  • 故障转移: 当 Master 被标记为客观下线(ODOWN),Sentinel 通过 Raft 协议选举 Leader,执行自动切换。
  • 优点: 自动故障转移、监控通知、客户端服务发现。
  • 适用: 中小规模部署,要求高可用但不需要数据分片。

2.3.3 Redis Cluster

  • 数据分片: 16384 个哈希槽(hash slot),每个节点负责一部分槽位。
  • 去中心化: 所有节点互联,客户端可直连任意节点,自动重定向。
  • 高可用: 每个主节点可配置从节点,主节点宕机后从节点自动提升。
  • 限制: 不支持多键事务(除非键在同一槽位);批量操作受限。
架构避坑: 在 OIDC 集成场景中,若使用 Redis Cluster,需注意 access_token 与 refresh_token 的键设计应包含哈希标签(hash tag),确保同一用户的令牌落在同一槽位,以支持原子操作。
Redis 高可用方案架构对比 主从复制 Master Slave 1 Slave 2 手动切换,无自动故障转移 哨兵模式 Master Slave Sentinel Sentinel 自动故障转移,Raft 选举 Redis Cluster Node 1 (M) Node 1 (S) Node 2 (M) Node 2 (S) 16384 槽位,去中心化 选型建议 主从:开发/测试环境 | 哨兵:中小规模生产(≤10 节点) | Cluster:大规模生产(≥10 节点,需分片)

2.4 高可用方案选型对比

维度 主从复制 哨兵模式 Redis Cluster
自动故障转移 ❌ 手动 ✅ 自动 ✅ 自动
数据分片 ❌ 无 ❌ 无 ✅ 16384 槽位
节点数要求 ≥2 ≥3(Sentinel) ≥6(3M+3S)
客户端复杂度 低 中(需支持 Sentinel) 高(需支持 Cluster 协议)
多键操作 ✅ 支持 ✅ 支持 ⚠️ 仅同槽位
典型延迟 低 低 中(跨节点转发)
适用规模 单机或小规模 中小规模(≤10 节点) 大规模(≥10 节点)
架构调优要点:
  • 在 OIDC 集成中,若令牌量级在百万以内,哨兵模式 配合读写分离即可满足高可用需求。
  • 若令牌量级达到千万级且需要水平扩展,Redis Cluster 是必然选择,但需提前规划哈希标签策略。
  • 持久化方面,混合持久化 是生产标配,RDB 用于快速恢复,AOF 用于最小化数据丢失。