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