Redis Cluster三节点高可用部署:香港服务器数据分片 + 自动故障切换完整实战

Redis Cluster三节点高可用部署:香港服务器数据分片 + 自动故障切换完整实战

单节点 Redis 有两个硬伤:内存上限受单机限制,任何故障都导致缓存不可用。Redis Cluster 通过将 16384 个哈希槽分散到多个主节点,实现数据水平扩展(突破单机内存限制)和自动故障转移(主节点故障时从节点自动晋升)。本文在香港服务器上搭建标准的 3 主 3 从 Redis Cluster。


一、Redis Cluster vs Sentinel 选型

维度Redis SentinelRedis Cluster
数据分片❌(所有数据在一台主节点)✅(数据分散到多主节点)
内存可扩展❌✅(加节点即扩容)
自动故障切换✅(Sentinel 监控)✅(节点间自动选举)
最少节点数1主 + 2哨兵3主 + 3从(最小配置)
多 Key 操作✅(无限制)⚠️(跨槽 MGET 等受限)
适合场景数据量 < 单机内存,需高可用数据量 > 单机内存,需扩展

二、节点规划

<code">
6 个 Redis 节点(3主3从),部署在 3 台服务器上:

服务器1(10.0.0.1):
  主节点1(端口 7001)+ 从节点4(端口 7004)

服务器2(10.0.0.2):
  主节点2(端口 7002)+ 从节点5(端口 7005)

服务器3(10.0.0.3):
  主节点3(端口 7003)+ 从节点6(端口 7006)

槽位分配:
  主节点1:槽 0-5460
  主节点2:槽 5461-10922
  主节点3:槽 10923-16383

从节点分配(交叉复制,避免同一服务器同时失去主从):
  从节点4(10.0.0.1)← 主节点2(10.0.0.2)的副本
  从节点5(10.0.0.2)← 主节点3(10.0.0.3)的副本
  从节点6(10.0.0.3)← 主节点1(10.0.0.1)的副本

三、配置文件(每台服务器执行)

<code"># 在三台服务器上都安装 Redis
apt update && apt install -y redis-server

# 每台服务器创建两个 Redis 实例(主+从各一个端口)
# 以服务器1为例,创建端口 7001 和 7004 的配置

for PORT in 7001 7004; do
    mkdir -p /etc/redis/cluster/$PORT
    mkdir -p /var/lib/redis/cluster/$PORT
    mkdir -p /var/log/redis/cluster

    cat > /etc/redis/cluster/$PORT/redis.conf << EOF
# 基础配置
port $PORT
bind 0.0.0.0
daemonize yes
requirepass redis_cluster_password_2026
masterauth redis_cluster_password_2026

# 集群配置
cluster-enabled yes
cluster-config-file /etc/redis/cluster/$PORT/nodes.conf
cluster-node-timeout 5000          # 节点超时5秒
cluster-announce-ip 10.0.0.1      # 本机IP(每台服务器修改)
cluster-announce-port $PORT
cluster-announce-bus-port 1$PORT

# 持久化
appendonly yes
appendfilename "appendonly-$PORT.aof"
dir /var/lib/redis/cluster/$PORT

# 日志
logfile /var/log/redis/cluster/$PORT.log

# 内存
maxmemory 2gb
maxmemory-policy allkeys-lru
EOF
done

# 启动两个 Redis 实例
redis-server /etc/redis/cluster/7001/redis.conf
redis-server /etc/redis/cluster/7004/redis.conf

# 验证启动
redis-cli -p 7001 -a redis_cluster_password_2026 ping

四、创建集群

<code"># 在任意一台服务器上执行(只需执行一次)
# 列出所有6个节点 IP:端口

redis-cli -a redis_cluster_password_2026 --cluster create \
  10.0.0.1:7001 \
  10.0.0.2:7002 \
  10.0.0.3:7003 \
  10.0.0.1:7004 \
  10.0.0.2:7005 \
  10.0.0.3:7006 \
  --cluster-replicas 1    # 每个主节点1个从节点

# 命令输出会显示槽位分配计划,输入 yes 确认

# 验证集群状态
redis-cli -p 7001 -a redis_cluster_password_2026 cluster info
redis-cli -p 7001 -a redis_cluster_password_2026 cluster nodes

五、Python 集群客户端

<code">from redis.cluster import RedisCluster, ClusterNode

# 创建集群连接(只需提供部分节点,客户端自动发现所有节点)
startup_nodes = [
    ClusterNode("10.0.0.1", 7001),
    ClusterNode("10.0.0.2", 7002),
    ClusterNode("10.0.0.3", 7003),
]

rc = RedisCluster(
    startup_nodes=startup_nodes,
    decode_responses=True,
    password="redis_cluster_password_2026",
    # 重试配置
    retry_on_timeout=True,
    socket_timeout=5,
    socket_connect_timeout=5,
)

# 基本操作(与单节点 Redis 完全相同)
rc.set("user:1001:name", "Alice")
rc.set("user:1001:email", "alice@example.com")
rc.get("user:1001:name")

# 注意:MSET 跨槽操作需要用 Hash Tag 确保相同槽位
# {user:1001} 是 Hash Tag,花括号内的内容决定槽位
rc.mset({
    "{user:1001}:name": "Alice",
    "{user:1001}:email": "alice@example.com",
    "{user:1001}:age": "30",
})
result = rc.mget("{user:1001}:name", "{user:1001}:email", "{user:1001}:age")

六、故障切换测试

<code"># 模拟主节点故障(杀死 7001 进程)
redis-cli -p 7001 -a redis_cluster_password_2026 DEBUG SLEEP 0
kill $(cat /var/run/redis_7001.pid)

# 观察集群状态变化(约5秒内完成故障切换)
watch -n 1 'redis-cli -p 7002 -a redis_cluster_password_2026 cluster nodes | grep master'

# 预期行为:
# 从节点6(10.0.0.3:7006,原来是7001的副本)自动晋升为主节点
# 原来槽 0-5460 由新主节点接管,服务不中断

# 重启原主节点后,自动以从节点身份重新加入集群
redis-server /etc/redis/cluster/7001/redis.conf
# 10秒内自动同步数据,重新成为从节点

七、集群扩容(在线添加节点)

<code"># 添加新主节点(服务器4上的7007端口)
redis-cli -a redis_cluster_password_2026 --cluster add-node \
  10.0.0.4:7007 \       # 新节点
  10.0.0.1:7001          # 现有节点(任意一个)

# 为新主节点添加从节点
redis-cli -a redis_cluster_password_2026 --cluster add-node \
  10.0.0.4:7008 \
  10.0.0.1:7001 \
  --cluster-slave \
  --cluster-master-id 新主节点ID

# 重新分配槽位(将现有槽位的一部分迁移到新节点)
redis-cli -a redis_cluster_password_2026 --cluster reshard \
  10.0.0.1:7001 \
  --cluster-from all \
  --cluster-to 新主节点ID \
  --cluster-slots 2000    # 迁移2000个槽位到新节点

八、监控集群状态

<code"># 查看集群整体信息
redis-cli -p 7001 -a redis_cluster_password_2026 cluster info

# 查看各节点状态
redis-cli -p 7001 -a redis_cluster_password_2026 cluster nodes

# 检查集群一致性(检测数据不一致)
redis-cli -a redis_cluster_password_2026 --cluster check 10.0.0.1:7001

# 实时监控(所有节点)
for port in 7001 7002 7003 7004 7005 7006; do
    echo "=== Port $port ===" 
    redis-cli -p $port -a redis_cluster_password_2026 info memory | grep used_memory_human
done

九、总结

Redis Cluster 3主3从配置在香港服务器集群上提供了真正的水平扩展能力和高可用保障。日常状态下数据均匀分布在三个主节点,任意一个主节点宕机时对应的从节点自动晋升,业务无感知。对于缓存数据量超过 10GB 或需要 99.99% 可用性的香港服务器应用,Redis Cluster 是必然的选择,而不是可选项。

Telegram