文章

Redis 高可用与集群方案

Redis 高可用与集群方案

概述

Redis 单机无法满足生产环境的要求(单点故障、内存上限、写入瓶颈),本文覆盖持久化(RDB/AOF)、Sentinel 哨兵、Cluster 集群和常见运维命令。

持久化:RDB vs AOF

维度RDB(快照)AOF(追加日志)
原理fork 子进程,COW 内存快照记录每条写命令到日志
文件大小小(压缩二进制)大(文本命令)
恢复速度慢(需重放命令)
数据安全可能丢最近一次快照后的数据最多丢 1 秒(everysec) / 不丢(always)
fork 风险内存大时 fork 耗时、COW 引起内存翻倍无 fork,但 IO 压力大
推荐频率save 900 1 + save 300 10 + save 60 10000appendfsync everysec

生产推荐:RDB + AOF 混合持久化(Redis 4.0+)

# redis.conf
save 900 1
save 300 10
save 60 10000

appendonly yes
appendfsync everysec                      # 每秒刷盘
aof-use-rdb-preamble yes                  # 混合持久化:AOF 头部用 RDB 格式 + 尾部 AOF
auto-aof-rewrite-percentage 100           # AOF 增长 100% 时触发 rewrite
auto-aof-rewrite-min-size 64mb            # AOF 至少 64MB 才考虑 rewrite

混合持久化:RDB 做全量快照、AOF 做增量,兼顾恢复速度和数据安全。

Sentinel 哨兵模式

架构

         ┌──────────┐
         │ Sentinel │  (监控 + 通知 + 故障转移)
         │ 集群 (≥3) │
         └────┬─────┘
    ┌─────────┼─────────┐
    ↓         ↓         ↓
┌──────┐ ┌──────┐ ┌──────┐
│Master│←→│Slave │←→│Slave │
└──────┘ └──────┘ └──────┘

Sentinel 配置

# sentinel.conf
sentinel monitor mymaster 192.168.1.1 6379 2    # 2 个 Sentinel 认为 Master 挂了才启动故障转移
sentinel down-after-milliseconds mymaster 5000    # 5s 无响应判定主观下线
sentinel failover-timeout mymaster 30000          # 故障转移超时
sentinel parallel-syncs mymaster 1                # 新 Master 上线后同时同步的 Slave 数

故障转移流程

1. Sentinel 发现 Master 主观下线(SDOWN)
2. 达到 quorum 数后判定客观下线(ODOWN)
3. 选举 Leader Sentinel 执行故障转移
4. 从 Slave 中选择最优(复制偏移量最大、优先级高)
5. 选举出的 Slave 执行 SLAVEOF NO ONE → 成为新 Master
6. 其他 Slave 切换到新 Master
7. 旧 Master 恢复后自动变为 Slave

Sentinel 限制

限制说明
本质是主从只有一个 Master,写入能力不扩展
客户端需感知客户端需支持 Sentinel 协议获取 Master 地址
切换期间不可写故障转移期间短暂不可用
数据丢失窗口异步复制 + 切换期间可能丢少量数据

Cluster 集群模式

核心概念

Redis Cluster = 分片(Sharding)+ 主从(Replication)

16384 个 Hash Slot:
  Master 0: 0-5460
  Master 1: 5461-10922
  Master 2: 10923-16383

每个 Master 有 N 个 Slave 副本

Cluster 配置

# redis.conf
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000                    # 节点不可达超时(ms)
cluster-require-full-coverage yes             # 有 Slot 不可用则拒绝请求
cluster-migration-barrier 1                   # Slave 迁移门槛

Cluster 创建与扩容

# 创建集群(6 个节点:3 主 + 3 从)
redis-cli --cluster create \
  192.168.1.1:6379 192.168.1.2:6379 192.168.1.3:6379 \
  192.168.1.4:6379 192.168.1.5:6379 192.168.1.6:6379 \
  --cluster-replicas 1

# 添加新 Master(扩容)
redis-cli --cluster add-node 192.168.1.7:6379 192.168.1.1:6379
redis-cli --cluster reshard 192.168.1.7:6379      # 重新分配 Slot

# 添加 Slave
redis-cli --cluster add-node 192.168.1.8:6379 192.168.1.1:6379 \
  --cluster-slave --cluster-master-id <master-id>

# 查看集群状态
redis-cli --cluster info 192.168.1.1:6379
redis-cli --cluster check 192.168.1.1:6379

Cluster 使用限制

限制说明应对
批量操作需 key 在同一 Slotmget 跨 Slot 报错用 Hash Tag {user}:1001:info {user}:1001:ext
事务仅单个 SlotMULTI/EXEC 不能跨节点设计保证相关 key 同一 Slot
Pipeline 按节点分组客户端需自行路由JedisCluster/lettuce 自动处理
Pub/Sub 影响所有节点发布消息广播到全集群大规模 Pub/Sub 建议用 Kafka
# Hash Tag 示例:确保同一 Slot
SET {user:1001}:name "Alice"
SET {user:1001}:email "alice@example.com"
# 两个 key 在同一个 Slot(只算 {} 内的部分做 hash)

Sentinel vs Cluster 选型

维度SentinelCluster
数据量< 内存单机上限可扩展到 TB 级
写入 QPS单机线性扩展
架构复杂度简单中等
运维成本
客户端兼容性需 Sentinel 感知需 Cluster 感知
多 key 操作原生支持需 Hash Tag
适用规模中小规模大规模/高写入

选型建议: 10 亿以下 key、写入 < 10 万 QPS → Sentinel;超大规模或快速增长 → Cluster。K8s 环境首选 Redis Operator。

运维命令速查

# === 信息查看 ===
redis-cli INFO                    # 完整信息
redis-cli INFO replication        # 复制状态
redis-cli INFO stats              # 统计信息
redis-cli INFO memory             # 内存使用
redis-cli INFO persistence        # 持久化状态

# === 延迟诊断 ===
redis-cli --latency               # 实时延迟
redis-cli --latency-history       # 延迟历史
redis-cli --latency-dist          # 延迟分布
redis-cli --intrinsic-latency 60  # 本机固有延迟(排除网络)

# === 内存诊断 ===
redis-cli --bigkeys               # BigKey 扫描
redis-cli MEMORY DOCTOR           # 内存分析建议
redis-cli MEMORY STATS            # 内存统计

# === 主从管理 ===
redis-cli SLAVEOF host port       # 将当前节点变为 Slave
redis-cli SLAVEOF NO ONE          # 将当前节点变为 Master
redis-cli ROLE                    # 查看当前角色

# === 慢查询日志 ===
redis-cli SLOWLOG GET 10          # 最近 10 条慢查询
redis-cli SLOWLOG LEN             # 慢查询条数
redis-cli SLOWLOG RESET           # 清空慢查询日志

# === 连接数 ===
redis-cli CLIENT LIST             # 所有连接
redis-cli CLIENT KILL addr:port   # KILL 连接
redis-cli CLIENT PAUSE 5000       # 暂停处理命令 5 秒(用于主从切换)

关键参数调优

# redis.conf 生产建议

# 内存
maxmemory 4gb                                  # 最大内存(避免 OOM)
maxmemory-policy allkeys-lru                   # 淘汰策略:LRU

# 持久化
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes

# 超时与连接
timeout 300                                    # 空闲连接超时(秒)
tcp-keepalive 300                              # TCP keepalive
maxclients 10000

# 慢查询日志
slowlog-log-slower-than 10000                  # 超过 10ms 记录(微秒)
slowlog-max-len 128

# 禁用危险命令
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""

常见问题 / 坑点

问题原因解决方案
RDB fork 导致延迟飙升大内存 fork 阻塞降低 save 频率 + 使用混合持久化 + 关闭 THP
AOF rewrite 时 IO 打满rewrite 大量写盘增大 auto-aof-rewrite-min-size + SSD
Sentinel 脑裂网络分区确保 quorum > N/2 节点 + min-slaves-to-write=1
Cluster 数据迁移时客户端重定向慢MOVED/ASK 重定向客户端保持连接池、支持 pipelining
OOM 被 OS killmaxmemory 未设或太小设置合理 maxmemory + maxmemory-policy
KEYS * 阻塞遍历全部 key(O(N))禁用 KEYS,用 SCAN 替代

关联知识

参考资源

学习时间

阶段时间备注
初次学习2026-07-14持久化 + Sentinel + Cluster + 运维

状态: 📖 已掌握 下次复习日期: 2026-08-14