Redis 高可用与高并发架构深度解析:从单机到集群演进
Redis 高可用与高并发的核心挑战
Redis 作为一个高性能的内存数据库,在现代互联网架构中承担着至关重要的角色。然而,在生产环境中使用单机版 Redis 会面临三个主要风险:单点故障导致服务不可用、单节点处理能力触达瓶颈、以及单机内存容量受限。为了应对这些问题,Redis 演进出了主从复制、哨兵模式和集群模式三种高可用方案。
一、主从复制(Master-Slave)的基础架构
主从复制是高可用的基石,通过将数据副本分布在多个实例上,实现读写分离。主库(Master)处理写请求并同步给从库(Slave),从库则主要承担读请求,从而减轻主库压力。
1. 数据同步机制
主从同步主要分为全量同步和增量同步:
- 全量同步:通常发生在从库首次连接主库时。主库通过生成 RDB 快照发送给从库,并在发送期间将新写入的命令存入 replication buffer,待 RDB 加载完成后再补发这些写命令。
- 增量同步:基于环形缓冲区
repl_backlog_buffer实现。主从库各自维护一个 offset(偏移量),当网络断开重连后,主库会根据 offset 差值将缓冲区中的增量数据发送给从库。如果断连时间过长导致缓冲区被覆盖,则会退化为全量同步。
2. 基础配置示例
在从节点的配置文件中指定主节点信息即可完成配置:
# slave.conf
port 6380
replicaof 127.0.0.1 6379
replica-read-only yes
二、哨兵模式(Sentinel):故障自动化转移
主从模式虽然实现了数据备份,但当主库宕机时需要人工介入。哨兵机制通过独立的进程实现自动化的监控、选主和通知。
1. 核心工作原理
- 监控:哨兵周期性向所有节点发送 PING,若超时未响应则判定为"主观下线"。
- 客观下线:当达到法定人数(Quorum)的哨兵都认为主库异常时,主库被标记为"客观下线"。
- 选主规则:哨兵会根据从库优先级、复制进度(offset 越接近主库评分越高)、运行 ID 大小等维度选举出新的主库。
2. 客户端接入示例(Java/Jedis)
使用哨兵模式时,客户端不再直接连接 Redis 节点,而是连接哨兵集群获取主节点地址:
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.100:26379");
sentinels.add("192.168.1.101:26379");
JedisSentinelPool sentinelPool = new JedisSentinelPool("my-master", sentinels);
try (Jedis jedisClient = sentinelPool.getResource()) {
jedisClient.set("site_name", "TechGuide");
System.out.println("Value: " + jedisClient.get("site_name"));
}
三、Redis Cluster:水平扩容与分片
当单机内存或并发量达到瓶颈时,哨兵模式也无法解决存储上限问题。Redis Cluster 采用无中心化架构,将数据分布到 16384 个哈希槽(Hash Slot)中,实现了真正的分布式存储。
1. 槽位分配逻辑
每个键通过 CRC16(key) % 16384 计算其所属槽位。集群中的每个主节点负责管理一部分槽位。例如:
- 节点 A:0 - 5460
- 节点 B:5461 - 10922
- 节点 C:10923 - 16383
2. Lettuce 客户端示例
Lettuce 是基于 Netty 的响应式客户端,支持异步操作,非常适合 Redis Cluster:
RedisURI clusterUri = RedisURI.Builder.redis("127.0.0.1", 7001)
.withPassword("your_password")
.build();
RedisClusterClient clusterClient = RedisClusterClient.create(clusterUri);
try (StatefulRedisClusterConnection<String, String> conn = clusterClient.connect()) {
RedisAdvancedClusterCommands<String, String> cmd = conn.sync();
cmd.set("cluster_key", "distributed_data");
System.out.println(cmd.get("cluster_key"));
}
clusterClient.shutdown();
四、高可用架构中的数据安全风险
尽管有复杂的切换机制,但在极端情况下仍可能出现数据丢失:
- 异步复制丢失:由于主从同步是异步的,主库宕机时若部分写命令尚未传给从库,这部分数据将丢失。
- 集群脑裂:网络分区导致出现两个主库。原主库在感知到失效前继续接收写入,待网络恢复后降级为从库,导致其本地数据被新主库覆盖。
解决方案:
可以通过配置 min-replicas-to-write 和 min-replicas-max-lag 参数来缓解:
# 要求至少有 1 个从库,且延迟不超过 10 秒,否则主库停止接收写入
min-replicas-to-write 1
min-replicas-max-lag 10
五、总结对比
在实际应用中:
- 读写分离需求:简单主从架构即可满足。
- 高可用(HA)要求:推荐使用 哨兵模式,适用于数据量在 GB 级别的场景。
- 海量数据与极致并发:必须采用 Cluster 集群,通过分片突破单机性能限制。