Redis怎么保证高可用?

1 个回答

  • 凤雪儿
    人总要要沉下心来过一段宁静而自省的日子来整理自己。
    # 一、我们要解决什么问题? * **实例挂了还能服务**(主机故障/进程崩溃/网络隔离)。 * **尽量少丢数据**(尽管 Redis 复制是异步的)。 * **自动故障转移** + 客户端**自动恢复连接**。 * **跨机房/可用区**抗单点。 # 二、构建 Redis 高可用的“积木” ## 1) 持久化(数据能回来,单机层面的可用性) * **RDB**:定期快照,恢复快、可能丢最近几秒。 * **AOF**:追加日志,`appendfsync`: * `always` 最安全最慢 * `everysec` 常用(≤1s 数据窗口) * `no` 性能好不保最近数据 * 推荐:**AOF everysec** + `aof-use-rdb-preamble yes`(重启更快)。 > 持久化不是“高可用”本身,但保证**重启后数据可恢复**。 ## 2) 复制(主从/主备,读写分离) * `replicaof <master ip> <port>` 建从库;复制是**异步**。 * **PSYNC** 支持**部分重同步**(有复制积压缓冲区,主短暂故障不必全量)。 * 可读从库:`replica-read-only yes`(默认 read-only)。 ## 3) Sentinel(主从 + 自动故障转移) * 多个 Sentinel 监控主从:心跳 → 判定主观下线(S\_DOWN)→ 达成**法定票数(quorum)** → 客观下线(O\_DOWN)→ 选举新主(对优先级/复制偏移量更大的从库优先)。 * 客户端通过 Sentinel **发现新主**并重连,或用连接中间件屏蔽切换。 * 典型拓扑:**1 主 2 从 + 3 Sentinel**(Sentinel 也要分不同主机/可用区)。 ## 4) Redis Cluster(分片 + 高可用) * 16384 \*\*槽(hash slots)\*\*分布在多个主节点,**每个主节点至少 1 个副本**。 * 任一主挂了,由其副本在多数派同意后**自动提升为主**;客户端需支持 cluster 协议(重定向 `MOVED/ASK`)。 * 适合**水平扩展**与自动故障转移同时实现:**读写路由 + 迁槽**。 ## 5) 托管服务/代理 * 托管:AWS ElastiCache / Azure Cache / GCP Memorystore——**跨 AZ、自动故障转移**。 * 代理:Twemproxy、Codis(屏蔽后端拓扑变化;注意功能限制与一致性)。 # 三、关键配置(把“可用”落到参数上) **复制与写安全** ```conf # 复制可靠性 repl-backlog-size 128mb # 复制积压缓存,降低全量的概率 repl-diskless-sync yes # 无盘全量复制,拉起更快 repl-timeout 60 # 写可用的“门槛” min-replicas-to-write 1 # 至少要有 N 个复制从机在线 min-replicas-max-lag 5 # 且复制延迟不超过 5s,否则暂停写(保护数据) ``` **持久化(性能/安全平衡)** ```conf appendonly yes appendfsync everysec no-appendfsync-on-rewrite yes # 重写期间避免频繁 fsync 抖动 aof-use-rdb-preamble yes ``` **Sentinel(示例)** ```conf # sentinel.conf sentinel monitor mymaster 10.0.0.1 6379 2 # quorum=2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1 ``` **Cluster(示例要点)** ```conf cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 ``` **客户端容错** * 连接池 + **自动重连** + **读写重试(幂等)**。 * 对 Sentinel:先连 Sentinel,拿主节点地址;主变更时刷新地址。 * 对 Cluster:使用支持 MOVED/ASK 的客户端;业务级**幂等**(避免重试造成副作用)。 # 四、数据丢失与一致性:能做到多“稳”? * **复制是异步**:主宕在从收到写之前,丢最近写。降低窗口的方法: * `appendfsync always`(代价大) * 写后执行 `WAIT N <ms>`:阻塞到 N 个副本确认(提升一致性,牺牲延迟/可用性) * `min-replicas-to-write + min-replicas-max-lag`:从机不足或延迟过大时**暂停写**(保数据优先) * **Sentinel/Cluster 选主**是基于心跳与投票,网络分区下可能**短暂不可写**以避免脑裂。 * **跨 AZ/机房部署**:主从跨区,Sentinel/Cluster 节点也要分散,提升容灾等级。 # 五、上线与运维要点(踩过的坑) 1. **多副本分散部署**:主、从、Sentinel(或各个 Cluster 主/从)分到不同主机/AZ。 2. **监控与告警**: * 指标:内存、连接、命中率、主从延迟、RDB/AOF 开销、`INFO replication`、`latency doctor`。 * 告警:复制断链、积压满、AOF 重写失败、内存逼近上限。 3. **容量与淘汰**:`maxmemory` + 合适的 `maxmemory-policy`(LFU/LRU/TTL)防止 OOM。 4. **备份与演练**:定期备份 AOF/RDB,演练故障转移(手动 kill -9 主、拔网线模拟)。 5. **滚动升级**:先从库、再主库(或 Cluster 逐主滚动),注意业务**幂等与重试**。 6. **一致性敏感写**:需要“强点”一致性的写路径,配合 `WAIT` 或业务幂等/确认链路。 7. **客户端限流/熔断**:故障切换期间的**瞬时失败**要能快速恢复,不要把 Redis 打爆。 ## 典型架构选择题 * **小规模、单 key 模式**:主从 + Sentinel(1主2从3哨兵)。 * **需要横向扩容与自动分片**:Redis Cluster(每主 1~2 从)。 * **极致稳定 + SLA**:托管云 Redis(多可用区)或自建 Cluster + 完备监控/演练。 * **强一致写**:`WAIT` / 业务幂等 + 对账补偿(性能换一致性)。 ### 一句话总结 > Redis 高可用 = **持久化保恢复** + **主从复制保副本** + **Sentinel/Cluster 自动故障转移** + **客户端容错重连**;在一致性上用 `WAIT`/“最少副本可写”与业务幂等做权衡,并用监控、备份、跨区部署把故障窗口压到最小。
    发布于 2025-08-12 17:47 •IP属地 贵州
    举报
    评论
    收藏