2. Redis核心机制回顾与云化适配

把 Redis 从物理机或自建虚拟机搬到云上,最容易踩的坑不是“能不能启动”,而是“原来那套高可用和持久化假设还成不成立”。持久化、复制、哨兵、集群这四套机制在云环境里并没有被替换,但它们的触发条件、网络路径、故障判定和运维边界都发生了变化。理解这些变化,才能回答一个更实际的问题:这个业务到底该选主从+哨兵,还是直接上集群?

持久化:RDB 与 AOF 在云盘上的行为差异

Redis 持久化解决的是“进程重启后数据还在不在”。RDB 是某一时刻的全量快照,文件紧凑、恢复快,适合做备份和跨环境迁移;AOF 记录写命令,按 appendfsync 策略决定落盘时机,everysec 是默认折中,最多丢约 1 秒数据。云化后最直接的变化来自存储介质:本地 NVMe 上 fsync 延迟常在百微秒级,而网络云盘(如 ESSD、EBS)单次刷盘延迟可能到毫秒级,AOF 重写和 RDB fork 期间更容易出现尾延迟抖动。

另一个变化是 fork 成本。RDB 和 AOF 重写都依赖 fork 写时复制,内存越大、写入越频繁,COW 页复制越多,主线程被拖慢的概率越高。云上实例规格往往内存更大,但 vCPU 与内存比不一定同步放大,因此建议:单实例内存超过 16GB 时,把 save 触发条件放宽,或把 RDB 放到从节点执行;AOF 使用 appendfsync everysec 并开启 aof-use-rdb-preamble yes,兼顾恢复速度与文件体积。若业务能接受分钟级数据回退,纯 RDB + 定期备份到对象存储,反而是云上最稳的组合。

复制:从“主从同步”到“跨可用区链路”

复制是哨兵和集群的地基。全量同步时,从节点先收到 RDB,再回放缓冲区中的增量命令;增量同步依赖 repl_backlog 环形缓冲。云环境里,主从常常跨可用区部署,RTT 从同机架的 0.1ms 变成 1~3ms,全量同步的 RDB 传输时间被拉长,期间主节点写入持续累积,一旦超出 backlog 或复制缓冲区上限,从节点就会再次触发全量同步,形成“同步风暴”。

因此云上复制要重点调三个参数:repl-backlog-size 按“峰值写入速率 × 预计断连时长”估算,例如峰值 50MB/s、容忍 60 秒断连,至少给 3GB;client-output-buffer-limit replica 要留足余量,避免从节点慢导致主节点主动断链;repl-diskless-sync yes 在云盘 IO 受限时能减少磁盘中转。判断复制是否健康,看 INFO replication 中的 master_link_status:up、master_last_io_seconds_ago 是否长期小于 10,以及 sync_full 是否持续增长——后者增长说明全量同步在反复发生。

Redis 四类核心机制在云环境下的行为变化与选型路径 持久化 RDB:全量快照,恢复快 AOF:命令日志,everysec 云盘 fsync 延迟升高 fork COW 拖慢主线程 → 大内存放宽 save → 从节点执行 RDB → 备份落对象存储 复制 全量 RDB + 增量回放 repl_backlog 环形缓冲 跨 AZ RTT 1~3ms 同步风暴风险上升 → backlog 按峰值估算 → 调大 replica 缓冲 → 开 diskless-sync 哨兵 主观下线 + 客观下线 quorum 投票选主 云网络抖动易误判 VIP/DNS 切换有延迟 → 调大 down-after → 哨兵跨 AZ 部署 → 客户端感知新主 集群 16384 槽位分片 Gossip 传播拓扑 MOVED/ASK 重定向 跨槽事务不可用 → 槽位均衡与迁移 → 客户端支持集群 → 避免大 key 倾斜 云环境选型判断路径 数据可容忍丢失? 分钟级回退可接受 是 单实例 + RDB 定期备份到 OSS 否 需要自动故障切换? 秒级恢复要求 是 数据量 < 单机内存? 如 ≤ 64GB 是 主从 + 哨兵 3 哨兵跨 AZ 否 Redis Cluster ≥3 主 3 从 客户端需支持 MOVED/ASK 客户端连哨兵 或 VIP/DNS

哨兵:故障判定在云网络下的“过敏反应”

哨兵负责监控、通知和自动选主。它通过 PING 判断主观下线,再由多个哨兵确认客观下线,最后用 Raft 式投票选出新主。云上最大的变量是网络:安全组策略调整、跨可用区抖动、宿主机迁移都可能让 PING 超时。如果 down-after-milliseconds 仍按同机房经验设成 3000ms,一次短暂抖动就可能触发切换,而切换期间客户端写入会失败。

更稳妥的做法是把 down-after-milliseconds 调到 10000~15000ms,failover-timeout 设为 60000ms 以上,并让 3 个哨兵分布在不同可用区。同时要明确:哨兵只解决“谁是新主”,不解决“客户端怎么找到新主”。客户端必须连接哨兵地址或由云厂商提供的代理/VIP,不能把主节点 IP 写死。切换后可用 INFO sentinel 查看 master0 地址是否更新,并用 redis-cli -h 新主 -p 端口 info replication 确认 role:master。

集群:分片带来的能力边界

Redis Cluster 用 16384 个槽位做分片,节点间通过 Gossip 交换拓扑,客户端根据槽位路由,遇到迁移中的槽会收到 ASK,遇到不属于当前节点的槽会收到 MOVED。云上部署集群,关键不是“能不能建起来”,而是“槽位是否均衡、客户端是否支持重定向”。如果大量 key 落在同一槽(例如用 user:{1001}:name 这类固定 hash tag),会出现数据倾斜,单节点内存和 QPS 先到瓶颈。

集群还带来两个必须接受的限制:跨槽的多 key 操作(如 MGET、事务、Lua 脚本)不可用;SELECT 只能使用 db0。因此选型时要先看业务访问模式:如果业务天然按租户或用户分片、且能接受客户端改造,集群是横向扩展的正解;如果业务大量使用多 key 事务或复杂 Lua,主从+哨兵反而更省心。

选型依据:一张判断表

判断维度主从 + 哨兵Redis Cluster
数据量单机内存可容纳(如 ≤64GB)超过单机内存,需水平分片
写入吞吐单主写入,受单核限制多主并行写入,可线性扩展
多 key 事务 / Lua完整支持仅同槽支持,跨槽不可用
客户端改造连接哨兵或 VIP 即可需支持 MOVED/ASK 重定向
故障切换哨兵投票,秒级到十秒级集群内自动 failover
运维复杂度较低较高,需关注槽位均衡
云上选型的一个实用原则:先问“数据能不能装进一台机器”,再问“客户端能不能接受重定向”。两个问题都答“能”,才考虑集群;否则优先主从+哨兵,把复杂度留给真正需要横向扩展的场景。
不要把哨兵和集群混用成“哨兵管集群”。集群自身具备故障转移能力,再叠加哨兵只会增加误判和运维负担。云托管 Redis 若已提供集群代理,应直接使用其接入点,而不是自行拼装哨兵。

最后回到云化适配的本质:持久化要重新评估云盘延迟与 fork 成本,复制要重新估算跨 AZ 的 backlog 与缓冲,哨兵要重新校准故障判定阈值,集群要重新检查槽位均衡与客户端能力。把这四件事分别落到参数和验证命令上,选型就不再是拍脑袋,而是有依据的工程决策。