Redis 集群配置:主从复制、Sentinel 与 Cluster 模式全面解析

小飞兽 Redis 4 次阅读 2026-07-29

前言

Redis 集群是实现数据高可用和水平扩展的关键。当单机 Redis 无法满足业务需求时,需要引入主从复制实现读写分离和故障容灾,使用 Sentinel 实现自动故障转移,或使用 Cluster 模式实现数据分片和水平扩展。本文全面解析这三种架构的工作原理与配置方法。

主从复制:数据同步的基础

主从复制是 Redis 高可用的基础。通过将数据同步到多个从节点,不仅可以实现读写分离(从节点承担读请求),还可以在主节点故障时快速切换。

-- 配置主从复制最简单的方式:在从节点上执行 SLAVEOF 命令
redis-cli SLAVEOF 192.168.1.100 6379

-- 断开主从关系
redis-cli SLAVEOF NO ONE

-- 查看复制状态
redis-cli INFO replication
-- role:master
-- connected_slaves:2
-- slave0:ip=192.168.1.101,port=6379,state=online,offset=12345
-- redis.conf 配置主从复制(从节点配置)
replicaof 192.168.1.100 6379
replica-serve-stale-data yes
replica-read-only yes

-- 主节点配置
maxmemory 2gb
maxmemory-policy allkeys-lru
# 应用层读写分离
class RedisReadWriteSplit:
    def __init__(self, master_host, replica_hosts):
        self.master = redis.Redis(host=master_host, port=6379)
        self.replicas = [redis.Redis(host=h, port=6379) for h in replica_hosts]
        self.replica_index = 0

    def write(self, key, value, ex=None):
        return self.master.set(key, value, ex=ex)

    def read(self, key):
        client = self.replicas[self.replica_index % len(self.replicas)]
        self.replica_index += 1
        return client.get(key)

Sentinel 自动故障转移

Sentinel 是 Redis 的高可用解决方案。Sentinel 是一个独立进程,监控主从节点的健康状态,在主节点故障时自动将从节点晋升为新的主节点,并通知应用层更新连接。

-- sentinel.conf 配置 Sentinel
port 26379
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster Admin@2026!
-- 启动 Sentinel
redis-sentinel /etc/redis/sentinel.conf

-- 查看 Sentinel 状态
redis-cli -p 26379 SENTINEL master mymaster
redis-cli -p 26379 SENTINEL slaves mymaster
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
from redis.sentinel import Sentinel

sentinel = Sentinel([
    ('192.168.1.100', 26379),
    ('192.168.1.101', 26379),
    ('192.168.1.102', 26379),
], socket_timeout=0.1)

-- 获取主节点连接
master = sentinel.master_for('mymaster', socket_timeout=0.1, password='Admin@2026!')

-- 获取从节点连接
replica = sentinel.slave_for('mymaster', socket_timeout=0.1, password='Admin@2026!')

def get_user(user_id):
    cache_key = f"user:{user_id}"
    data = replica.get(cache_key)  -- 读从节点
    if data:
        return json.loads(data)
    user = db.query("SELECT * FROM users WHERE id = %s", (user_id,))
    if user:
        master.setex(cache_key, 3600, json.dumps(user))  -- 写主节点
    return user

Cluster 模式:水平扩展

当单机 Redis 的内存无法容纳所有数据时,需要使用 Redis Cluster 进行水平分片。Redis Cluster 将数据划分为 16384 个槽位(slot),每个节点负责一部分槽位。

-- Redis Cluster 至少需要 6 个节点(3 主 3 从)
-- 启动 6 个 Redis 节点
for port in 7000 7001 7002 7003 7004 7005; do
    redis-server /redis-cluster/$port/redis.conf --daemonize yes
done

-- 创建 Cluster
redis-cli --cluster create \
    192.168.1.100:7000 \
    192.168.1.100:7001 \
    192.168.1.100:7002 \
    192.168.1.100:7003 \
    192.168.1.100:7004 \
    192.168.1.100:7005 \
    --cluster-replicas 1

-- 查看 Cluster 状态
redis-cli -p 7000 CLUSTER NODES
redis-cli -p 7000 CLUSTER INFO
-- 每个节点的 redis.conf 配置
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 15000
appendonly yes
maxmemory 2gb
maxmemory-policy allkeys-lru
from redis.cluster import RedisCluster

rc = RedisCluster(
    host='192.168.1.100',
    port=7000,
    password='Admin@2026!',
    skip_full_coverage_check=True,
    read_from_replicas=True,
)

-- 使用方式和普通 Redis 客户端完全一致
rc.set('key:1', 'value')
rc.get('key:1')

-- 批量操作会被自动拆分为多个节点的并行请求
keys = [f'user:{i}' for i in range(100)]
values = rc.mget(keys)

Cluster 的槽位管理

-- 查看槽位分配
redis-cli -p 7000 CLUSTER SLOTS

-- 手动重新分配槽位(扩容时使用)
redis-cli --cluster reshard 192.168.1.100:7000 \
    --cluster-from <source_node_id> \
    --cluster-to <target_node_id> \
    --cluster-slots 1000

-- 添加新节点到集群
redis-cli --cluster add-node 192.168.1.100:7006 192.168.1.100:7000

-- 删除节点(必须先将其槽位迁移走)
redis-cli --cluster del-node 192.168.1.100:7006 <node_id>

三种架构的对比与选择

| 特性 | 主从+Sentinel | Redis Cluster |
|------|-------------|---------------|
| 数据分片 | 无 | 有,16384 槽位分片 |
| 写扩展能力 | 受单主节点限制 | 多主节点并行写 |
| 读扩展能力 | 从节点分担 | 所有节点分担 |
| 故障恢复 | Sentinel 自动切换 | 自动故障转移 |
| 最小节点数 | 2 | 6 |

-- 选择建议:
-- 1. 数据量 < 10GB,读写压力 < 5 万 QPS:单节点 + 主从复制 + Sentinel
-- 2. 数据量 > 10GB,读写压力 > 5 万 QPS:Redis Cluster
-- 3. 写入量特别大:Redis Cluster 多主节点并行写入
-- 4. 数据量中等但对可用性要求极高:主从 + Sentinel + 双写

常见问题

Q1:Redis Cluster 可以使用布隆过滤器或 Geo 指令吗?
可以,但需要注意这些指令可能涉及多个槽位。GEO 命令的 key 涉及多个节点上的 key 时可能会报错。确保 GEO 相关操作使用相同的 key。

Q2:Redis Cluster 可以支持跨机房部署吗?
可以,但跨机房网络延迟会影响 Cluster 的心跳和故障检测。建议在同一城市内的多机房部署。如果需要跨城市容灾,建议使用主从 + Sentinel 架构。

Q3:从节点长期不同步数据怎么办?
检查 INFO replication 中的 master_link_status,如果为 down,说明主从连接已断开。可能原因:网络问题、主节点负载过高、从节点资源不足。解决方案:检查网络、重建主从复制、或从备份恢复。

延伸阅读

  • Redis 持久化机制
  • Redis 数据类型完全指南
  • Redis 分布式锁实现
  • Redis 官方文档:Redis Cluster https://redis.io/docs/management/scaling/