Redis 集群部署与高可用配置指南

前言

Redis 作为高性能的键值存储系统,广泛应用于缓存、会话管理、消息队列等场景。本文详细介绍 Redis 集群的部署步骤、高可用配置及运维最佳实践,帮助构建稳定可靠的 Redis 集群环境。

一、架构规划

1.1 集群拓扑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                ┌─────────────────┐
│ HAProxy/VIP │
│ (负载均衡) │
└────────┬────────┘

┌─────────────────┼─────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Master 1 │ │ Master 2 │ │ Master 3 │
│ (0-5460) │ │ (5461-10922)│ │(10923-16383)│
│ Port: 6379 │ │ Port: 6379 │ │ Port: 6379 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Slave 1 │ │ Slave 2 │ │ Slave 3 │
│ Port: 6380 │ │ Port: 6380 │ │ Port: 6380 │
└─────────────┘ └─────────────┘ └─────────────┘

1.2 硬件要求

组件 数量 CPU 内存 磁盘 网络
Master 3 4 核 8GB SSD 50GB 千兆
Slave 3 4 核 8GB SSD 50GB 千兆
Sentinel 3 2 核 2GB 10GB 千兆

1.3 软件版本

  • Redis: 7.2.x (推荐最新稳定版)
  • 操作系统:Ubuntu 22.04 LTS / CentOS 7.9+
  • 内核版本:4.15+

二、系统准备

2.1 系统优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
# redis_sysctl.sh - Redis 系统优化脚本

# 关闭透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

# 优化内存分配
echo 1 > /proc/sys/vm/overcommit_memory

# 调整 SOMAXCONN
sysctl -w net.core.somaxconn=65535

# 调整 TCP backlog
sysctl -w net.ipv4.tcp_max_syn_backlog=65535

# 禁用 swap (可选,根据内存情况)
# swapoff -a

# 持久化配置
cat >> /etc/sysctl.conf << EOF
# Redis optimizations
vm.overcommit_memory = 1
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
EOF

# 开机自动关闭透明大页
cat >> /etc/rc.local << EOF
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
EOF
chmod +x /etc/rc.local

2.2 安装 Redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Ubuntu/Debian
apt update
apt install -y redis-server redis-tools

# 或从源码编译 (推荐生产环境)
wget https://download.redis.io/releases/redis-7.2.4.tar.gz
tar xzf redis-7.2.4.tar.gz
cd redis-7.2.4
make MALLOC=jemalloc
make install

# 验证安装
redis-server --version
redis-cli --version

三、集群配置

3.1 Master 节点配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# /etc/redis/redis-6379.conf (Master 1)

# 基础配置
bind 0.0.0.0
port 6379
daemonize yes
pidfile /var/run/redis/redis-6379.pid
loglevel notice
logfile /var/log/redis/redis-6379.log

# 数据目录
dir /var/lib/redis/6379

# 持久化配置
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump-6379.rdb

# AOF 持久化
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 集群配置
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
cluster-replica-validity-factor 10
cluster-migration-barrier 1
cluster-require-full-coverage no

# 内存管理
maxmemory 6gb
maxmemory-policy allkeys-lru

# 安全配置
requirepass YourStrongPassword123!
masterauth YourStrongPassword123!

# 网络优化
tcp-backlog 65535
timeout 0
tcp-keepalive 300

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

3.2 Slave 节点配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# /etc/redis/redis-6380.conf (Slave 1)

# 基础配置 (与 Master 类似,端口不同)
bind 0.0.0.0
port 6380
daemonize yes
pidfile /var/run/redis/redis-6380.pid
loglevel notice
logfile /var/log/redis/redis-6380.log
dir /var/lib/redis/6380

# 持久化配置 (Slave 可关闭 AOF 减少 IO)
appendonly no
save ""

# 集群配置
cluster-enabled yes
cluster-config-file nodes-6380.conf
cluster-node-timeout 5000

# 内存管理
maxmemory 6gb
maxmemory-policy allkeys-lru

# 安全配置
requirepass YourStrongPassword123!
masterauth YourStrongPassword123!

3.3 创建目录并设置权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# 创建必要目录
mkdir -p /var/run/redis
mkdir -p /var/log/redis
mkdir -p /var/lib/redis/{6379,6380}

# 设置权限
chown -R redis:redis /var/run/redis
chown -R redis:redis /var/log/redis
chown -R redis:redis /var/lib/redis

chmod 755 /var/run/redis
chmod 755 /var/log/redis
chmod 750 /var/lib/redis

四、集群初始化

4.1 启动所有节点

1
2
3
4
5
6
7
8
9
10
11
# 在所有节点上启动 Redis
systemctl start redis@6379
systemctl start redis@6380

# 或使用配置文件启动
redis-server /etc/redis/redis-6379.conf
redis-server /etc/redis/redis-6380.conf

# 验证启动
ps aux | grep redis
netstat -tlnp | grep redis

4.2 创建集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash
# create_cluster.sh

REDIS_PASSWORD="YourStrongPassword123!"
MASTERS="192.168.1.101 192.168.1.102 192.168.1.103"
SLAVES="192.168.1.104 192.168.1.105 192.168.1.106"

# 等待所有节点启动
echo "Waiting for nodes to be ready..."
for host in $MASTERS $SLAVES; do
while ! redis-cli -h $host -p 6379 -a "$REDIS_PASSWORD" ping 2>/dev/null | grep -q PONG; do
sleep 1
done
while ! redis-cli -h $host -p 6380 -a "$REDIS_PASSWORD" ping 2>/dev/null | grep -q PONG; do
sleep 1
done
done

echo "All nodes are ready. Creating cluster..."

# 创建集群 (3 主 3 从)
redis-cli --cluster create \
192.168.1.101:6379 192.168.1.102:6379 192.168.1.103:6379 \
192.168.1.104:6380 192.168.1.105:6380 192.168.1.106:6380 \
--cluster-replicas 1 \
-a "$REDIS_PASSWORD" \
--cluster-yes

echo "Cluster created successfully!"

4.3 验证集群状态

1
2
3
4
5
6
7
8
9
10
11
12
# 检查集群信息
redis-cli -a YourStrongPassword123! --cluster info 192.168.1.101:6379

# 检查集群节点
redis-cli -a YourStrongPassword123! --cluster check 192.168.1.101:6379

# 查看节点状态
redis-cli -h 192.168.1.101 -p 6379 -a YourStrongPassword123! cluster nodes

# 测试集群
redis-cli -a YourStrongPassword123! -c set test_key "hello cluster"
redis-cli -a YourStrongPassword123! -c get test_key

五、Sentinel 高可用配置

5.1 Sentinel 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# /etc/redis/sentinel-26379.conf

port 26379
daemonize yes
pidfile /var/run/redis/sentinel-26379.pid
logfile /var/log/redis/sentinel-26379.log
dir /var/lib/redis/sentinel

# 监控主节点
sentinel monitor mymaster 192.168.1.101 6379 2
sentinel auth-pass mymaster YourStrongPassword123!

# 故障判定
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

# 通知脚本 (可选)
# sentinel notification-script mymaster /var/redis/notify.sh
# sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

# 日志
loglevel notice

5.2 启动 Sentinel

1
2
3
4
5
6
7
# 在 3 个不同节点启动 Sentinel
redis-server /etc/redis/sentinel-26379.conf --sentinel

# 验证 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

5.3 故障转移测试

1
2
3
4
5
6
7
8
# 手动触发故障转移
redis-cli -p 26379 sentinel failover mymaster

# 模拟 Master 故障
redis-cli -h 192.168.1.101 -p 6379 -a YourStrongPassword123! debug sleep 30

# 观察故障转移日志
tail -f /var/log/redis/sentinel-26379.log

六、监控与告警

6.1 关键监控指标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/bash
# redis_monitor.sh - Redis 监控脚本

REDIS_HOST="192.168.1.101"
REDIS_PORT="6379"
REDIS_PASSWORD="YourStrongPassword123!"

# 获取关键指标
INFO=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" INFO)

# 内存使用
USED_MEMORY=$(echo "$INFO" | grep "used_memory:" | cut -d: -f2 | tr -d '\r')
MAX_MEMORY=$(echo "$INFO" | grep "maxmemory:" | cut -d: -f2 | tr -d '\r')
MEMORY_USAGE=$((USED_MEMORY * 100 / MAX_MEMORY))

# 连接数
CONNECTED_CLIENTS=$(echo "$INFO" | grep "connected_clients:" | cut -d: -f2 | tr -d '\r')

# 命中率
KEYSPACE_HITS=$(echo "$INFO" | grep "keyspace_hits:" | cut -d: -f2 | tr -d '\r')
KEYSPACE_MISSES=$(echo "$INFO" | grep "keyspace_misses:" | cut -d: -f2 | tr -d '\r')
if [ $((KEYSPACE_HITS + KEYSPACE_MISSES)) -gt 0 ]; then
HIT_RATE=$((KEYSPACE_HITS * 100 / (KEYSPACE_HITS + KEYSPACE_MISSES)))
else
HIT_RATE=0
fi

# 持久化状态
RDB_LAST_STATUS=$(echo "$INFO" | grep "rdb_last_bgsave_status:" | cut -d: -f2 | tr -d '\r')
AOF_LAST_STATUS=$(echo "$INFO" | grep "aof_last_bgrewrite_status:" | cut -d: -f2 | tr -d '\r')

# 输出指标 (可用于 Prometheus)
echo "redis_memory_usage_percent $MEMORY_USAGE"
echo "redis_connected_clients $CONNECTED_CLIENTS"
echo "redis_cache_hit_rate $HIT_RATE"
echo "redis_rdb_status $([ "$RDB_LAST_STATUS" = "ok" ] && echo 1 || echo 0)"
echo "redis_aof_status $([ "$AOF_LAST_STATUS" = "ok" ] && echo 1 || echo 0)"

# 告警检查
if [ $MEMORY_USAGE -gt 85 ]; then
echo "ALERT: Memory usage is above 85%"
fi

if [ "$RDB_LAST_STATUS" != "ok" ]; then
echo "ALERT: RDB last save failed"
fi

6.2 Prometheus 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
# prometheus.yml
scrape_configs:
- job_name: 'redis'
static_configs:
- targets: ['192.168.1.101:9121', '192.168.1.102:9121', '192.168.1.103:9121']
metrics_path: /scrape
params:
module: [redis]

# 使用 redis_exporter
# docker run -d --name redis_exporter -p 9121:9121 \
# oliver006/redis_exporter \
# --redis.addr=192.168.1.101:6379 --redis.password=YourStrongPassword123!

6.3 Grafana 告警规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# alerting_rules.yml
groups:
- name: redis_alerts
interval: 30s
rules:
- alert: RedisMemoryHigh
expr: redis_memory_usage_percent > 85
for: 5m
labels:
severity: warning
annotations:
summary: "Redis 内存使用率过高"
description: "实例 {{ $labels.instance }} 内存使用率 {{ $value }}%"

- alert: RedisDown
expr: redis_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Redis 实例宕机"
description: "实例 {{ $labels.instance }} 无法连接"

- alert: RedisPersistenceFailed
expr: redis_rdb_status == 0 or redis_aof_status == 0
for: 5m
labels:
severity: warning
annotations:
summary: "Redis 持久化失败"
description: "实例 {{ $labels.instance }} 持久化操作失败"

七、备份与恢复

7.1 备份脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/bin/bash
# redis_backup.sh

BACKUP_DIR="/data/redis_backup"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
REDIS_PASSWORD="YourStrongPassword123!"

mkdir -p "$BACKUP_DIR"

# 触发 RDB 保存
redis-cli -a "$REDIS_PASSWORD" BGSAVE

# 等待保存完成
while true; do
STATUS=$(redis-cli -a "$REDIS_PASSWORD" LASTSAVE)
sleep 2
NEW_STATUS=$(redis-cli -a "$REDIS_PASSWORD" LASTSAVE)
if [ "$STATUS" != "$NEW_STATUS" ]; then
break
fi
done

# 复制 RDB 文件
for port in 6379 6380; do
RDB_FILE="/var/lib/redis/${port}/dump-${port}.rdb"
if [ -f "$RDB_FILE" ]; then
cp "$RDB_FILE" "${BACKUP_DIR}/dump-${port}_${DATE}.rdb"
gzip "${BACKUP_DIR}/dump-${port}_${DATE}.rdb"
fi
done

# 清理旧备份
find "$BACKUP_DIR" -name "*.rdb.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: $DATE"

7.2 恢复步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
# redis_restore.sh

BACKUP_FILE="$1"
TARGET_PORT="${2:-6379}"
REDIS_PASSWORD="YourStrongPassword123!"

if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup_file.rdb.gz> [port]"
exit 1
fi

# 停止 Redis
systemctl stop redis@${TARGET_PORT}

# 解压备份
gunzip -c "$BACKUP_FILE" > "/var/lib/redis/${TARGET_PORT}/dump-${TARGET_PORT}.rdb"

# 设置权限
chown redis:redis "/var/lib/redis/${TARGET_PORT}/dump-${TARGET_PORT}.rdb"

# 启动 Redis
systemctl start redis@${TARGET_PORT}

# 验证
redis-cli -p $TARGET_PORT -a "$REDIS_PASSWORD" DBSIZE

八、性能调优

8.1 内存优化

1
2
3
4
5
6
7
8
9
10
11
12
# 内存淘汰策略
# volatile-lru: 只淘汰有过期时间的键
# allkeys-lru: 淘汰所有键 (推荐缓存场景)
# volatile-ttl: 淘汰即将过期的键
# noeviction: 不淘汰,写操作返回错误
maxmemory-policy allkeys-lru

# 内存碎片整理
activedefrag yes
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100

8.2 网络优化

1
2
3
4
5
6
7
8
9
# 客户端输出缓冲区限制
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

# TCP 参数
tcp-backlog 65535
tcp-keepalive 300
timeout 0

8.3 慢查询分析

1
2
3
4
5
6
7
8
9
# 查看慢查询
redis-cli -a YourStrongPassword123! SLOWLOG GET 10

# 配置慢查询阈值
redis-cli -a YourStrongPassword123! CONFIG SET slowlog-log-slower-than 10000
redis-cli -a YourStrongPassword123! CONFIG SET slowlog-max-len 128

# 实时监控
redis-cli -a YourStrongPassword123! MONITOR

九、常见问题排查

9.1 集群状态异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 检查集群状态
redis-cli -a YourStrongPassword123! --cluster check 192.168.1.101:6379

# 修复集群
redis-cli -a YourStrongPassword123! --cluster fix 192.168.1.101:6379

# 重新分片
redis-cli -a YourStrongPassword123! --cluster reshard 192.168.1.101:6379

# 添加新节点
redis-cli -a YourStrongPassword123! --cluster add-node 192.168.1.107:6379 192.168.1.101:6379

# 删除节点
redis-cli -a YourStrongPassword123! --cluster del-node 192.168.1.101:6379 <node-id>

9.2 内存问题

1
2
3
4
5
6
7
8
9
10
11
12
# 查看内存使用详情
redis-cli -a YourStrongPassword123! INFO memory

# 查看大键
redis-cli -a YourStrongPassword123! --bigkeys

# 查看热键 (需要开启监控)
redis-cli -a YourStrongPassword123! --hotkeys

# 内存分析
redis-cli -a YourStrongPassword123! MEMORY DOCTOR
redis-cli -a YourStrongPassword123! MEMORY STATS

9.3 持久化问题

1
2
3
4
5
6
7
8
9
10
11
12
# 检查持久化状态
redis-cli -a YourStrongPassword123! INFO persistence

# 手动触发保存
redis-cli -a YourStrongPassword123! BGSAVE # RDB
redis-cli -a YourStrongPassword123! BGREWRITEAOF # AOF

# 检查 AOF 文件
redis-check-aof --fix /var/lib/redis/6379/appendonly-6379.aof

# 检查 RDB 文件
redis-check-rdb /var/lib/redis/6379/dump-6379.rdb

十、运维 checklist

日常巡检

  • 检查集群状态 (cluster info)
  • 检查内存使用率 (<80%)
  • 检查连接数 (是否异常增长)
  • 检查持久化状态 (RDB/AOF last status)
  • 检查慢查询日志
  • 检查系统资源 (CPU/内存/磁盘/网络)
  • 检查备份是否成功

定期维护

  • 每月执行内存分析 (memory doctor)
  • 每季度评估容量规划
  • 每半年进行故障转移演练
  • 每年升级 Redis 版本 (评估兼容性)

总结

Redis 集群部署需要考虑多个方面:

  1. 架构设计:合理规划主从节点和分片
  2. 系统优化:关闭透明大页、调整内核参数
  3. 高可用:配置 Sentinel 实现自动故障转移
  4. 监控告警:建立完善的监控体系
  5. 备份恢复:定期备份并验证恢复流程
  6. 性能调优:根据业务场景调整配置参数

遵循本文档的最佳实践,可以构建稳定、高性能、易维护的 Redis 集群环境。


文档版本:1.0 | 最后更新:2026-03-10