Redis高可用部署与集群管理实战

本文详解Redis高可用架构设计,从主从复制到哨兵模式再到Cluster集群的完整实践。

前言

Redis作为最流行的缓存数据库:

  • 高性能:10万+ QPS
  • 丰富的数据结构
  • 简单易用

但单机Redis存在问题:

  • 单点故障
  • 容量有限
  • 无法水平扩展

今天来讲Redis的高可用部署方案。


一、高可用架构选型

1.1 架构对比

架构 特点 适用场景
主从复制 读写分离,手动故障转移 小规模,读多写少
哨兵模式 自动故障转移 中等规模
Cluster集群 分片存储,高可用 大规模,数据量大

1.2 如何选择

复制代码
数据量 < 10GB,QPS < 5万:主从复制
数据量 < 50GB,需要自动故障转移:哨兵模式
数据量 > 50GB,需要分片:Cluster集群

二、主从复制

2.1 架构图

复制代码
┌─────────────┐
│   Master    │
│ 192.168.1.1 │
│   :6379     │
└──────┬──────┘
│ 同步
┌───┴───┐
↓       ↓
┌──────┐ ┌──────┐
│Slave1│ │Slave2│
│ .2   │ │ .3   │
└──────┘ └──────┘

2.2 Docker部署

yaml 复制代码
# docker-compose.yml
version: '3.8'

services:
  redis-master:
    image: redis:7
    container_name: redis-master
    ports:
      - "6379:6379"
    volumes:
      - ./master/data:/data
      - ./master/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf

  redis-slave1:
    image: redis:7
    container_name: redis-slave1
    ports:
      - "6380:6379"
    volumes:
      - ./slave1/data:/data
      - ./slave1/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf
    depends_on:
      - redis-master

  redis-slave2:
    image: redis:7
    container_name: redis-slave2
    ports:
      - "6381:6379"
    volumes:
      - ./slave2/data:/data
      - ./slave2/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf
    depends_on:
      - redis-master

2.3 配置文件

Master配置:

bash 复制代码
# master/redis.conf
bind 0.0.0.0
port 6379
requirepass yourpassword
masterauth yourpassword
appendonly yes

Slave配置:

bash 复制代码
# slave1/redis.conf
bind 0.0.0.0
port 6379
requirepass yourpassword
masterauth yourpassword
replicaof redis-master 6379
appendonly yes
replica-read-only yes

2.4 验证同步

bash 复制代码
# 连接Master
redis-cli -h 127.0.0.1 -p 6379 -a yourpassword

# 查看复制状态
127.0.0.1:6379> INFO replication
# role:master
# connected_slaves:2

# 写入数据
127.0.0.1:6379> SET test "hello"

# 连接Slave验证
redis-cli -h 127.0.0.1 -p 6380 -a yourpassword
127.0.0.1:6380> GET test
"hello"

三、哨兵模式

3.1 架构图

复制代码
┌────────────────────────────────┐
        │         Sentinel集群           │
        │  ┌─────┐ ┌─────┐ ┌─────┐     │
        │  │ S1  │ │ S2  │ │ S3  │     │
        │  └──┬──┘ └──┬──┘ └──┬──┘     │
        └─────┼───────┼───────┼────────┘
              │       │       │ 监控
       ┌──────┴───────┴───────┴──────┐
       ↓                              ↓
┌─────────────┐              ┌─────────────┐
│   Master    │──同步──────→│   Slave     │
└─────────────┘              └─────────────┘

故障转移:Master挂了 → Sentinel投票 → 提升Slave为Master

3.2 部署配置

yaml 复制代码
# docker-compose.yml 添加哨兵
  sentinel1:
    image: redis:7
    container_name: sentinel1
    ports:
      - "26379:26379"
    volumes:
      - ./sentinel1/sentinel.conf:/etc/redis/sentinel.conf
    command: redis-sentinel /etc/redis/sentinel.conf

  sentinel2:
    image: redis:7
    container_name: sentinel2
    ports:
      - "26380:26379"
    volumes:
      - ./sentinel2/sentinel.conf:/etc/redis/sentinel.conf
    command: redis-sentinel /etc/redis/sentinel.conf

  sentinel3:
    image: redis:7
    container_name: sentinel3
    ports:
      - "26381:26379"
    volumes:
      - ./sentinel3/sentinel.conf:/etc/redis/sentinel.conf
    command: redis-sentinel /etc/redis/sentinel.conf

Sentinel配置:

bash 复制代码
# sentinel.conf
port 26379
sentinel monitor mymaster redis-master 6379 2
sentinel auth-pass mymaster yourpassword
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

3.3 故障转移测试

bash 复制代码
# 停止Master
docker stop redis-master

# 查看Sentinel日志
docker logs sentinel1

# +sdown master mymaster 192.168.1.1 6379
# +odown master mymaster 192.168.1.1 6379 #quorum 2/2
# +switch-master mymaster 192.168.1.1 6379 192.168.1.2 6379

# Slave已提升为新Master

3.4 客户端连接

java 复制代码
// Java连接哨兵
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.1:26379");
sentinels.add("192.168.1.2:26379");
sentinels.add("192.168.1.3:26379");

JedisSentinelPool pool = new JedisSentinelPool(
    "mymaster",
    sentinels,
    config,
    "yourpassword"
);

四、Cluster集群

4.1 架构图

复制代码
┌────────────┐ ┌────────────┐ ┌────────────┐
│  Master1   │ │  Master2   │ │  Master3   │
│ Slot 0-5460│ │Slot 5461-  │ │Slot 10923- │
│            │ │   10922    │ │   16383    │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
      │              │              │
      ↓              ↓              ↓
┌────────────┐ ┌────────────┐ ┌────────────┐
│  Slave1    │ │  Slave2    │ │  Slave3    │
└────────────┘ └────────────┘ └────────────┘

数据按Key的CRC16值分配到16384个槽位
每个Master负责一部分槽位

4.2 部署

bash 复制代码
# 创建6个节点(3主3从)
for port in 7001 7002 7003 7004 7005 7006; do
    mkdir -p cluster/${port}
    cat > cluster/${port}/redis.conf << EOF
port ${port}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
requirepass yourpassword
masterauth yourpassword
EOF
done

# 启动节点
for port in 7001 7002 7003 7004 7005 7006; do
    docker run -d --name redis-${port} \
        -p ${port}:${port} -p 1${port}:1${port} \
        -v $(pwd)/cluster/${port}:/data \
        redis:7 redis-server /data/redis.conf
done

# 创建集群
redis-cli --cluster create \
    192.168.1.1:7001 192.168.1.1:7002 192.168.1.1:7003 \
    192.168.1.1:7004 192.168.1.1:7005 192.168.1.1:7006 \
    --cluster-replicas 1 -a yourpassword

4.3 集群操作

bash 复制代码
# 连接集群(-c表示集群模式)
redis-cli -c -p 7001 -a yourpassword

# 查看集群状态
127.0.0.1:7001> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_known_nodes:6

# 查看节点信息
127.0.0.1:7001> CLUSTER NODES

# 设置Key(自动路由)
127.0.0.1:7001> SET user:1 "test"
-> Redirected to slot [8106] located at 192.168.1.1:7002
OK

4.4 扩容

bash 复制代码
# 添加新节点
redis-cli --cluster add-node 192.168.1.1:7007 192.168.1.1:7001 -a yourpassword

# 重新分配槽位
redis-cli --cluster reshard 192.168.1.1:7001 -a yourpassword

# 添加从节点
redis-cli --cluster add-node 192.168.1.1:7008 192.168.1.1:7007 \
    --cluster-slave --cluster-master-id <master-id> -a yourpassword

五、跨机房/多站点部署

5.1 场景挑战

复制代码
需求:
- 总部机房:3台服务器
- 分部机房:3台服务器
- 需要搭建6节点Cluster

挑战:
- 两个机房网络不通
- Redis Cluster需要节点互通

5.2 解决方案

使用组网软件(如星空组网)打通网络:

复制代码
组网后的部署:

┌─────────────────────────────────────────────────────────┐
│                    组网虚拟局域网                         │
│                                                          │
│  ┌──────────────────┐      ┌──────────────────┐         │
│  │     总部机房      │      │     分部机房      │         │
│  │                  │      │                  │         │
│  │  Master1(10.10.0.1)     │  Master2(10.10.0.4)│         │
│  │  Master3(10.10.0.2)     │  Slave1 (10.10.0.5)│         │
│  │  Slave2 (10.10.0.3)     │  Slave3 (10.10.0.6)│         │
│  │                  │      │                  │         │
│  └──────────────────┘      └──────────────────┘         │
│                                                          │
└─────────────────────────────────────────────────────────┘

配置:

bash 复制代码
# 各节点配置中使用组网IP
# 节点1(总部)
cluster-announce-ip 10.10.0.1
cluster-announce-port 7001
cluster-announce-bus-port 17001

# 节点4(分部)
cluster-announce-ip 10.10.0.4
cluster-announce-port 7001
cluster-announce-bus-port 17001

# 创建集群时使用组网IP
redis-cli --cluster create \
    10.10.0.1:7001 10.10.0.2:7001 10.10.0.3:7001 \
    10.10.0.4:7001 10.10.0.5:7001 10.10.0.6:7001 \
    --cluster-replicas 1 -a yourpassword

效果:

  • 跨机房节点通过组网IP互通
  • Cluster正常工作
  • 加密传输,安全可靠

5.3 跨机房容灾策略

复制代码
主从分布策略:
- 每个Master的Slave部署在不同机房
- 机房故障时,另一机房的Slave可提升为Master

┌──────────────┐         ┌──────────────┐
│    总部      │         │    分部      │
│  Master1 ←───────同步──→ Slave1       │
│  Master2 ←───────同步──→ Slave2       │
│  Slave3  ←───────同步──→ Master3      │
└──────────────┘         └──────────────┘

六、运维管理

6.1 监控指标

bash 复制代码
# 关键指标
redis-cli INFO | grep -E "connected_clients|used_memory|hit_rate|ops_per_sec"

# 监控脚本
#!/bin/bash
HOSTS=("10.10.0.1:6379" "10.10.0.2:6379" "10.10.0.3:6379")

for host in ${HOSTS[@]}; do
    echo "=== $host ==="
    redis-cli -h ${host%:*} -p ${host#*:} -a yourpassword INFO | \
        grep -E "connected_clients|used_memory_human|keyspace_hits"
done

6.2 数据备份

bash 复制代码
# RDB备份
redis-cli -a yourpassword BGSAVE

# 备份文件位置
/data/dump.rdb

# 定时备份脚本
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
redis-cli -a yourpassword BGSAVE
sleep 5
cp /data/dump.rdb /backup/redis_${DATE}.rdb

6.3 性能优化

bash 复制代码
# redis.conf优化

# 内存策略
maxmemory 4gb
maxmemory-policy allkeys-lru

# 持久化优化(写入性能)
appendfsync everysec

# 连接优化
tcp-backlog 511
timeout 300
tcp-keepalive 300

# 慢查询日志
slowlog-log-slower-than 10000
slowlog-max-len 128

6.4 常用命令

bash 复制代码
# 查看大Key
redis-cli -a yourpassword --bigkeys

# 查看内存分析
redis-cli -a yourpassword --memkeys

# 慢查询
redis-cli -a yourpassword SLOWLOG GET 10

# 客户端列表
redis-cli -a yourpassword CLIENT LIST

七、常见问题

7.1 主从同步延迟

bash 复制代码
# 查看延迟
redis-cli -a yourpassword INFO replication | grep lag

# 解决方案
# 1. 增加repl-backlog-size
repl-backlog-size 256mb

# 2. 网络优化(使用组网降低延迟)

7.2 Cluster MOVED错误

bash 复制代码
# 客户端需要使用集群模式
# Java: JedisCluster
# Python: redis-py-cluster

JedisCluster cluster = new JedisCluster(nodes, config);

7.3 内存不足

bash 复制代码
# 查看内存使用
redis-cli -a yourpassword INFO memory

# 清理过期Key
redis-cli -a yourpassword --scan --pattern "*" | head -1000 | xargs redis-cli DEL

# 设置过期时间
EXPIRE key 3600

八、总结

Redis高可用部署要点:

架构 节点数 自动故障转移 分片
主从复制 2+
哨兵模式 5+(含哨兵)
Cluster 6+

我的建议:

  • 小项目:主从复制够用
  • 一般项目:哨兵模式
  • 大数据量:Cluster集群
  • 跨机房:组网 + Cluster

关键配置:

复制代码
1. 密码认证
2. 持久化策略
3. 内存限制
4. 监控告警

参考资料

  1. Redis官方文档:https://redis.io/docs/
  2. Redis Cluster扩展指南:https://redis.io/learn/operate/redis-at-scale/scalability/
  3. Redis集群API文档:https://redis.io/docs/latest/operate/rs/clusters/

💡 建议:生产环境至少使用哨兵模式,避免单点故障。定期备份数据,监控内存使用。

相关推荐
JSON_L24 分钟前
Fastadmin中实现敏感词管理
数据库·php·fastadmin
不是起点的终点1 小时前
【实战】Python 一键生成数据库说明文档(对接阿里云百炼 AI,输出 Word 格式)
数据库·python·阿里云
2301_813599553 小时前
Go语言怎么做秒杀系统_Go语言秒杀系统实战教程【实用】
jvm·数据库·python
NCIN EXPE8 小时前
redis 使用
数据库·redis·缓存
MongoDB 数据平台8 小时前
为编码代理引入 MongoDB 代理技能和插件
数据库·mongodb
极客on之路8 小时前
mysql explain type 各个字段解释
数据库·mysql
代码雕刻家8 小时前
MySQL与SQL Server的基本指令
数据库·mysql·sqlserver
lThE ANDE8 小时前
开启mysql的binlog日志
数据库·mysql
hERS EOUS8 小时前
nginx 代理 redis
运维·redis·nginx
yejqvow128 小时前
CSS如何控制placeholder文字的颜色_使用--placeholder伪元素
jvm·数据库·python