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/

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

相关推荐
DolphinDB智臾科技3 小时前
DolphinDB 面向金融交易与定价的统一数据模型
数据库·时序数据库
檀越剑指大厂3 小时前
时序数据库性能之战:金仓数据库如何在复杂场景下反超 InfluxDB?
数据库·时序数据库
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue图书借阅管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
数据与人3 小时前
mongodb报错Sort exceeded memory limit of 104857600 bytes
数据库·mongodb
程序员鱼皮3 小时前
消息队列从入门到跑路,保姆级教程!傻子可懂
数据库·程序员·消息队列
C++业余爱好者4 小时前
SQL语言家族入门指南:标准SQL、T-SQL与PL/SQL详解
数据库·sql
白驹过隙^^4 小时前
OB-USP-AGENT安装使用方法
数据库·经验分享·网络协议·tcp/ip·github·ssl
计算机程序设计小李同学4 小时前
基于Python的在线零食购物商城系统的设计与实现
数据库·sqlite
Java爱好狂.4 小时前
Java面试Redis核心知识点整理!
java·数据库·redis·分布式锁·java面试·后端开发·java八股文