文章导读

本文将详细介绍如何使用 Docker Compose 部署主从结构 Redis 集群,包括以下内容:

  • Redis 主从复制原理及优势
  • 部署环境准备与配置
  • Docker Compose 配置与部署步骤
  • 主从复制配置与测试验证
  • 哨兵模式配置与故障转移
  • 性能优化与安全配置
  • 监控与维护最佳实践

通过本文的指导,您将能够快速搭建一个稳定、高效的 Redis 主从集群,实现数据的高可用性和读写分离。

企业级 Docker Compose 部署 Redis 主从复制集群

1. 技术架构概览

1.1 Redis 主从复制原理

Redis 主从复制是一种基于异步复制的数据同步机制,通过将主 Redis 服务器(Master)的数据复制到从 Redis 服务器(Slave),实现数据的多副本存储和读写分离。这是构建 Redis 高可用集群的基础方案,广泛应用于生产环境中。

1.1.1 主从复制的核心技术优势

  • 服务连续性保障:当主节点故障时,可以快速切换到从节点,确保业务服务不中断
  • 线性性能扩展:通过增加从节点数量,实现读性能的线性扩展,支撑高并发业务场景
  • 数据安全防护:从节点作为实时备份,结合定期全量备份,构建多层次数据安全体系
  • 跨地域灾备:从节点可部署在不同数据中心,实现跨地域灾备,应对区域性灾难
  • 零停机维护:通过从节点进行版本升级、配置变更等维护操作,实现业务无感知

1.1.2 主从复制的底层工作机制

全量同步(首次同步/断点续传失败)

  1. 从节点:向主节点发送 PSYNC ? -1 命令,请求同步数据
  2. 主节点:执行 BGSAVE 命令生成 RDB 快照文件,同时将期间的写命令记录到复制缓冲区
  3. 主节点:发送 +FULLRESYNC <runid> <offset> 响应,开始全量同步
  4. 主节点:将 RDB 文件发送给从节点
  5. 从节点:接收并加载 RDB 文件,清空原有数据
  6. 主节点:将复制缓冲区中的写命令发送给从节点
  7. 从节点:执行这些写命令,与主节点数据达到一致

增量同步(正常运行时)

  1. 主节点:将写命令发送给从节点
  2. 从节点:执行这些写命令,保持与主节点数据一致
  3. 心跳检测:主从节点通过 PING 命令保持连接
  4. 偏移量同步:主从节点通过复制偏移量(replication offset)确保数据一致性

1.1.3 主从复制的技术细节深度解析

复制偏移量(Replication Offset)

  • 主节点:记录发送的字节数(master_repl_offset)
  • 从节点:记录接收的字节数(slave_repl_offset)
  • 用于检测数据同步状态和断点续传
  • 监控指标:复制延迟 = 主节点偏移量 - 从节点偏移量

复制积压缓冲区(Replication Backlog Buffer)

  • 主节点维护的固定大小环形缓冲区
  • 存储最近发送的写命令
  • 用于从节点断线重连时的增量同步
  • 默认大小 1MB,生产环境建议设置为 10-100MB
  • 计算公式:缓冲区大小 = 主节点写入速率(字节/秒) × 最大网络中断时间(秒)

运行 ID(Run ID)

  • 每个 Redis 实例启动时生成的唯一标识(40 个随机十六进制字符)
  • 用于从节点识别主节点变化
  • 主节点重启后 Run ID 变化,从节点会触发全量同步
  • 可通过 INFO server 命令查看

复制超时机制

  • 从节点:repl-timeout 配置(默认 60 秒)
  • 用于检测主节点是否超时
  • 超时后从节点会重新发起复制请求

复制压缩

  • 通过 repl-disable-tcp-nodelay 配置控制
  • 设置为 yes:禁用 TCP_NODELAY,减少网络包数量,适合远距离复制
  • 设置为 no:启用 TCP_NODELAY,数据实时性更好,适合局域网复制

1.2 企业级 Redis 架构设计

1.2.1 企业级架构拓扑

一主多从架构(标准生产方案)

  • 1 个主节点:处理写操作,复制数据到从节点
  • 2-5 个从节点:处理读操作,作为数据备份
  • 3 个哨兵节点:监控主从状态,实现自动故障转移
  • 1 个负载均衡器:分发读请求到从节点
  • 1 套监控系统:实时监控集群状态

级联复制架构(大规模部署)

  • 主节点 → 中间从节点(1-2 个) → 下层从节点(多个)
  • 减少主节点的复制压力,适合 10+ 从节点场景
  • 中间从节点需要开启 replicaofreplica-read-only
  • 下层从节点指向中间从节点

混合云架构(跨地域灾备)

  • 本地数据中心:部署主节点和 1-2 个从节点
  • 云环境:部署 1-2 个从节点
  • 实现跨地域灾备,应对区域性灾难
  • 需要考虑网络延迟对复制的影响

多活架构(核心业务)

  • 双主架构:两个主节点,双向复制
  • 配合哨兵模式实现自动故障转移
  • 适合对可用性要求极高的核心业务

1.2.2 企业级技术栈与组件选型

组件版本用途配置文件选型理由
Redis7.0+ LTS主从复制核心conf/master.conf, conf/slave.conf7.0+ LTS 版本提供 ACL、集群增强、内存优化等企业级特性,稳定性和性能均优
Docker20.10.24+容器化运行环境-提供隔离性和一致性,简化部署和迁移
Docker Compose1.29.2+多容器编排docker-compose.yml支持服务依赖管理、网络配置和资源限制,适合多实例部署
Redis Sentinel7.0+高可用监控conf/sentinel.conf实现自动故障检测和转移,确保服务连续性
Nginx1.24.0+负载均衡conf/nginx/nginx.conf轻量级高性能负载均衡器,支持健康检查和会话保持
Prometheus2.45.0+监控系统conf/prometheus/prometheus.yml时序数据库,适合监控指标的采集和存储
Grafana9.5.15+可视化监控conf/grafana/provisioning丰富的仪表盘和告警功能,提供直观的监控视图
Redis Exporter1.37.0+Redis 指标采集-专门用于采集 Redis 实例的详细监控指标

1.2.3 企业级性能和容量规划

内存规划

  • 主节点:数据大小 × 1.5(预留空间) + 复制缓冲区
  • 从节点:与主节点相同或略大(+20%)
  • 预留 30-40% 内存作为操作系统和其他进程使用
  • 计算公式:总内存 = 数据大小 × (1 + 0.5 + 0.3) = 数据大小 × 1.8

网络规划

  • 主从复制网络:建议独立网络,带宽 ≥ 1Gbps
  • 应用访问网络:根据并发连接数和数据传输量确定
  • 跨地域复制:考虑网络延迟,建议使用专线或高质量 VPN
  • 带宽需求:主节点写入速率 × 从节点数量 × 1.2(冗余)

存储规划

  • RDB/AOF 文件存储:SSD 存储,IOPS ≥ 500
  • 备份存储:独立存储系统,容量 = 数据大小 × 3(保留多份备份)
  • 持久化文件路径:建议使用独立挂载点

计算资源规划

  • CPU:根据并发连接数和操作复杂度,主节点建议 4-8 核
  • 内存:根据数据大小和内存策略,主节点建议 8-32GB
  • IO:根据持久化策略和操作频率,建议 SSD 存储

不同规模部署的资源配置参考

部署规模CPU内存存储网络适用场景
小型部署2-4 核4-8GB100GB SSD1Gbps开发测试、小型应用
中型部署4-8 核8-16GB200GB SSD1Gbps+中小型生产环境
大型部署8-16 核16-64GB500GB SSD10Gbps大型生产环境
超大型部署16+ 核64GB+1TB+ NVMe25Gbps+核心业务系统

云环境资源配置参考

云服务提供商实例类型CPU内存存储类型适用场景
AWSt3.medium2 核4GBgp3开发测试
AWSm5.xlarge4 核16GBgp3小型生产
AWSr5.2xlarge8 核64GBio2中型生产
AWSr5.4xlarge16 核128GBio2大型生产
阿里云ecs.c6.large2 核8GBESSD开发测试
阿里云ecs.r6.xlarge4 核32GBESSD小型生产
阿里云ecs.r6.2xlarge8 核64GBESSD中型生产
阿里云ecs.r6.4xlarge16 核128GBESSD大型生产

2. 企业级部署准备

2.1 企业级环境要求

2.1.1 软件环境要求

软件最低版本推荐版本安装方式
Docker19.03.0+20.10.24+官方脚本
Docker Compose1.25.0+1.29.2+官方脚本
Linux 内核4.19+5.4+系统更新
OpenSSL1.1.1+3.0+系统包管理器

2.1.2 硬件资源要求

部署规模CPU内存存储网络适用场景
小型部署2-4 核4-8GB100GB SSD1Gbps开发测试、小型应用
中型部署4-8 核8-16GB200GB SSD1Gbps+中小型生产环境
大型部署8-16 核16-64GB500GB SSD10Gbps大型生产环境
超大型部署16+ 核64GB+1TB+ NVMe25Gbps+核心业务系统

2.2 企业级系统调优

2.2.1 Linux 内核调优

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
# 编辑系统内核参数
sudo nano /etc/sysctl.conf

# 添加以下配置
# 网络优化
net.core.somaxconn = 65535 # 最大连接数
net.ipv4.tcp_max_syn_backlog = 65535 # 最大半连接数
net.ipv4.tcp_fin_timeout = 30 # FIN 超时时间
net.ipv4.tcp_keepalive_time = 300 # 保活时间
net.ipv4.tcp_keepalive_probes = 5 # 保活探测次数
net.ipv4.tcp_keepalive_intvl = 15 # 保活探测间隔
net.ipv4.tcp_max_tw_buckets = 5000 # 最大 TIME_WAIT 数
net.ipv4.tcp_fastopen = 3 # 启用 TCP Fast Open
net.core.netdev_max_backlog = 65535 # 网络设备缓冲区

# 内存管理
vm.swappiness = 10 # 交换空间使用倾向
vm.max_map_count = 262144 # 最大内存映射数
vm.overcommit_memory = 1 # 内存过度分配策略
vm.overcommit_ratio = 90 # 内存过度分配比例

# 文件系统
fs.file-max = 655350 # 最大文件描述符
fs.aio-max-nr = 1048576 # 最大异步 I/O 数

# 应用配置
sudo sysctl -p

2.2.2 文件描述符调优

1
2
3
4
5
6
7
8
9
10
11
12
13
# 编辑文件描述符限制
sudo nano /etc/security/limits.conf

# 添加以下配置
* soft nofile 65535
* hard nofile 655350
root soft nofile 65535
root hard nofile 655350

# 编辑 PAM 配置
sudo nano /etc/pam.d/common-session
# 添加以下行
session required pam_limits.so

2.2.3 CPU 调度优化

1
2
3
4
5
# 设置 CPU 性能模式
sudo cpupower frequency-set -g performance

# 禁用 CPU 节能模式
sudo systemctl disable cpufrequtils

2.3 企业级目录结构

2.3.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
# 创建主目录结构
mkdir -p redis-master-slave/{
data/{master,slave1,slave2,sentinel1,sentinel2,sentinel3,prometheus,grafana},
conf/{master,slave,sentinel,nginx,prometheus,grafana},
scripts/{backup,monitor,maintenance,ha},
logs/{master,slave1,slave2,sentinel,nginx,prometheus,grafana},
ssl,
backup,
temp
}

# 进入部署目录
cd redis-master-slave

# 设置权限
chmod -R 755 data/ # 数据目录
chmod -R 700 ssl/ # SSL 证书目录(严格权限)
chmod -R 755 scripts/ # 脚本目录
chmod +x scripts/**/*.sh # 执行权限
chmod -R 644 conf/ # 配置文件目录
chmod -R 755 logs/ # 日志目录
chmod -R 750 backup/ # 备份目录
chmod -R 755 temp/ # 临时目录

# 设置 Docker 卷权限
sudo chown -R 999:999 data/master/ # Redis 用户(999)
sudo chown -R 999:999 data/slave1/
sudo chown -R 999:999 data/slave2/
sudo chown -R 999:999 data/sentinel*/
sudo chown -R 65534:65534 data/prometheus/ # nobody 用户
sudo chown -R 472:472 data/grafana/ # Grafana 用户

2.3.2 目录结构说明

目录用途权限要求存储类型
data/master主节点数据文件755 (redis:redis)SSD/NVMe
data/slave*从节点数据文件755 (redis:redis)SSD/NVMe
data/sentinel*哨兵节点数据755 (redis:redis)SSD
data/prometheusPrometheus 数据755 (nobody:nobody)SSD
data/grafanaGrafana 数据755 (grafana:grafana)SSD
conf/*各服务配置文件644 (root:root)任何
scripts/*自动化脚本755 (root:root)任何
logs/*各服务日志755 (root:root)任何
sslSSL 证书700 (root:root)任何
backup备份文件750 (root:root)大容量存储
temp临时文件755 (root:root)任何

2.3.3 企业级配置文件管理

配置文件版本控制

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
# 初始化 Git 仓库
git init

# 创建 .gitignore 文件
cat > .gitignore << 'EOF'
# 数据目录
data/

# 日志目录
logs/

# 备份目录
backup/

# 临时目录
temp/

# SSL 证书
ssl/

# 环境变量文件
.env

# IDE 配置
.idea/
.vscode/
EOF

# 提交初始配置
git add .
git commit -m "Initial commit: Redis master-slave cluster configuration"

配置文件模板管理

1
2
3
4
5
6
7
8
# 创建配置模板目录
mkdir -p templates/

# 复制配置文件作为模板
cp -r conf/ templates/

# 替换敏感信息为变量
sed -i 's/YourStrongPassword/{{REDIS_MASTER_PASSWORD}}/g' templates/master/redis.conf

2.4 企业级配置文件

2.4.1 主节点配置(conf/master/master.conf)

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
55
56
57
58
59
60
61
62
63
64
65
66
67
# 基础配置
bind 0.0.0.0 # 绑定地址(容器环境推荐)
port 6379 # 监听端口
daemonize no # 后台运行(容器环境设置为 no)
pidfile /var/run/redis/redis-server.pid # PID 文件路径
logfile "" # 日志文件(容器环境设为空,使用标准输出)
dir /data # 数据目录

# RDB 持久化配置
save 3600 1 # 1小时内有1个变更就持久化
save 600 100 # 10分钟内有100个变更就持久化
save 300 1000 # 5分钟内有1000个变更就持久化
rdbcompression yes # 启用 RDB 压缩
rdbchecksum yes # 启用 RDB 校验和
dbfilename dump.rdb # RDB 文件名

# AOF 持久化配置
appendonly yes # 启用 AOF 持久化
appendfilename "appendonly.aof" # AOF 文件名
appendfsync everysec # AOF 同步策略(everysec 平衡性能和安全性)
no-appendfsync-on-rewrite yes # 重写时不执行同步,提升性能
auto-aof-rewrite-percentage 100 # AOF 重写触发百分比
auto-aof-rewrite-min-size 64mb # AOF 重写最小文件大小
appenddirname "appendonlydir" # AOF 目录名(Redis 7.0+)

# 混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes # 启用混合持久化

# 安全配置
requirepass ${REDIS_MASTER_PASSWORD} # 主节点密码
masterauth ${REDIS_MASTER_PASSWORD} # 从节点连接密码

# 内存配置
maxmemory 2gb # 最大内存(根据实际内存调整)
maxmemory-policy volatile-lru # 内存淘汰策略
maxmemory-samples 5 # 淘汰采样数量

# 复制配置
repl-disable-tcp-nodelay no # 启用 TCP_NODELAY,数据实时性更好
repl-backlog-size 10mb # 复制积压缓冲区大小
repl-backlog-ttl 3600 # 复制积压缓冲区过期时间
repl-diskless-sync no # 禁用无盘同步
repl-diskless-sync-delay 5 # 无盘同步延迟
repl-ping-replica-period 10 # 从节点 ping 主节点周期
repl-timeout 60 # 复制超时时间

# 从节点只读
replica-read-only yes # 从节点只读

# 慢查询日志
slowlog-log-slower-than 10000 # 慢查询阈值(微秒)
slowlog-max-len 128 # 慢查询日志长度

# 客户端配置
timeout 0 # 客户端超时时间(0 表示禁用)
tcp-keepalive 300 # TCP 保活时间
maxclients 10000 # 最大客户端连接数

# 线程配置
io-threads 4 # IO 线程数(根据 CPU 核心数调整)
io-threads-do-reads yes # IO 线程处理读操作

# 其他配置
hz 100 # Redis 时钟频率
dynamic-hz yes # 动态调整时钟频率
latency-monitor-threshold 0 # 延迟监控阈值
notify-keyspace-events ""

2.4.2 从节点配置(conf/slave/slave.conf)

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 基础配置
bind 0.0.0.0 # 绑定地址(容器环境推荐)
port 6379 # 监听端口
daemonize no # 后台运行(容器环境设置为 no)
pidfile /var/run/redis/redis-server.pid # PID 文件路径
logfile "" # 日志文件(容器环境设为空,使用标准输出)
dir /data # 数据目录

# RDB 持久化配置
save 3600 1 # 1小时内有1个变更就持久化
save 600 100 # 10分钟内有100个变更就持久化
save 300 1000 # 5分钟内有1000个变更就持久化
rdbcompression yes # 启用 RDB 压缩
rdbchecksum yes # 启用 RDB 校验和
dbfilename dump.rdb # RDB 文件名

# AOF 持久化配置
appendonly yes # 启用 AOF 持久化
appendfilename "appendonly.aof" # AOF 文件名
appendfsync everysec # AOF 同步策略(everysec 平衡性能和安全性)
no-appendfsync-on-rewrite yes # 重写时不执行同步,提升性能
auto-aof-rewrite-percentage 100 # AOF 重写触发百分比
auto-aof-rewrite-min-size 64mb # AOF 重写最小文件大小
appenddirname "appendonlydir" # AOF 目录名(Redis 7.0+)

# 混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes # 启用混合持久化

# 安全配置
requirepass ${REDIS_SLAVE_PASSWORD} # 从节点密码
masterauth ${REDIS_MASTER_PASSWORD} # 主节点连接密码

# 内存配置
maxmemory 2.4gb # 最大内存(比主节点大 20%)
maxmemory-policy volatile-lru # 内存淘汰策略
maxmemory-samples 5 # 淘汰采样数量

# 复制配置
repl-disable-tcp-nodelay no # 启用 TCP_NODELAY,数据实时性更好
repl-backlog-size 10mb # 复制积压缓冲区大小
repl-backlog-ttl 3600 # 复制积压缓冲区过期时间
repl-diskless-sync no # 禁用无盘同步
repl-diskless-sync-delay 5 # 无盘同步延迟
repl-ping-replica-period 10 # 从节点 ping 主节点周期
repl-timeout 60 # 复制超时时间
replica-serve-stale-data yes # 从节点服务过期数据
replica-read-only yes # 从节点只读

# 从节点优先级(用于哨兵故障转移)
replica-priority 100 # 优先级(0-1000,数字越小优先级越高)

# 慢查询日志
slowlog-log-slower-than 10000 # 慢查询阈值(微秒)
slowlog-max-len 128 # 慢查询日志长度

# 客户端配置
timeout 0 # 客户端超时时间(0 表示禁用)
tcp-keepalive 300 # TCP 保活时间
maxclients 10000 # 最大客户端连接数

# 线程配置
io-threads 4 # IO 线程数(根据 CPU 核心数调整)
io-threads-do-reads yes # IO 线程处理读操作

# 其他配置
hz 100 # Redis 时钟频率
dynamic-hz yes # 动态调整时钟频率
latency-monitor-threshold 0 # 延迟监控阈值
notify-keyspace-events ""

2.4.3 哨兵配置(conf/sentinel/sentinel.conf)

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
# 基础配置
bind 0.0.0.0 # 绑定地址(容器环境推荐)
port 26379 # 哨兵端口
daemonize no # 后台运行(容器环境设置为 no)
pidfile /var/run/redis/sentinel.pid # PID 文件路径
logfile "" # 日志文件(容器环境设为空,使用标准输出)
dir /data # 数据目录

# 监控主节点
sentinel monitor mymaster redis-master 6379 2 # 监控名为 mymaster 的主节点,需要 2 个哨兵同意故障转移

# 主节点密码
sentinel auth-pass mymaster ${REDIS_MASTER_PASSWORD}

# 故障检测配置
sentinel down-after-milliseconds mymaster 30000 # 主节点多少毫秒无响应视为下线

# 故障转移配置
sentinel parallel-syncs mymaster 1 # 故障转移时同时同步的从节点数
sentinel failover-timeout mymaster 180000 # 故障转移超时时间

# 脚本配置
sentinel notification-script mymaster /scripts/notification.sh # 故障通知脚本
sentinel client-reconfig-script mymaster /scripts/reconfig.sh # 客户端重配置脚本

# 其他配置
sentinel deny-scripts-reconfig yes # 禁止通过 SENTINEL CONFIG 命令修改脚本路径

2.4.4 环境变量配置(.env)

创建企业级 .env 文件,集中管理所有敏感信息和配置参数:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# ==========================================
# Redis 核心配置
# ==========================================

# 主节点配置
REDIS_MASTER_PASSWORD=YourStrongMasterPassword2024! # 主节点密码
REDIS_MASTER_PORT=6379 # 主节点端口

# 从节点配置
REDIS_SLAVE_PASSWORD=YourStrongSlavePassword2024! # 从节点密码
REDIS_SLAVE1_PORT=6380 # 从节点 1 端口
REDIS_SLAVE2_PORT=6381 # 从节点 2 端口

# 哨兵配置
REDIS_SENTINEL_PORT1=26379 # 哨兵 1 端口
REDIS_SENTINEL_PORT2=26380 # 哨兵 2 端口
REDIS_SENTINEL_PORT3=26381 # 哨兵 3 端口

# ==========================================
# 服务器资源配置
# ==========================================

# 主机资源信息
HOST_MEMORY=16G # 主机内存总量
HOST_CPU_CORES=8 # 主机 CPU 核心数

# 容器资源限制
CONTAINER_MASTER_MEMORY=2g # 主节点容器内存限制
CONTAINER_MASTER_CPU=4 # 主节点容器 CPU 限制
CONTAINER_SLAVE_MEMORY=2.4g # 从节点容器内存限制
CONTAINER_SLAVE_CPU=4 # 从节点容器 CPU 限制
CONTAINER_SENTINEL_MEMORY=512m # 哨兵容器内存限制
CONTAINER_SENTINEL_CPU=1 # 哨兵容器 CPU 限制

# ==========================================
# 备份配置
# ==========================================

# 备份策略
BACKUP_RETENTION_DAYS=7 # 备份保留天数
BACKUP_DIR=/backup # 备份目录
BACKUP_CRON_SCHEDULE=0 2 * * * # 备份执行计划(每天凌晨 2 点)
BACKUP_COMPRESSION=ON # 启用备份压缩

# ==========================================
# 监控配置
# ==========================================

# Prometheus 配置
PROMETHEUS_PORT=9090 # Prometheus 端口
PROMETHEUS_RETENTION=15d # 监控数据保留天数

# Grafana 配置
GRAFANA_PORT=3000 # Grafana 端口
GRAFANA_ADMIN_USER=admin # Grafana 管理员用户名
GRAFANA_ADMIN_PASSWORD=YourStrongGrafanaPassword2024! # Grafana 管理员密码
GRAFANA_DASHBOARD_ID=763 # Redis 监控仪表盘 ID

# ==========================================
# 网络配置
# ==========================================

# 网络子网
NETWORK_SUBNET=172.22.0.0/16 # Docker 网络子网
NETWORK_GATEWAY=172.22.0.1 # Docker 网络网关

# 负载均衡配置
NGINX_PORT=6389 # Nginx 负载均衡端口

# ==========================================
# 安全配置
# ==========================================

# SSL 配置
SSL_ENABLED=1 # 启用 SSL
SSL_CERT_PATH=/etc/redis/ssl # SSL 证书路径

# 密码策略
PASSWORD_VALIDATION_LENGTH=12 # 密码最小长度
PASSWORD_VALIDATION_COMPLEXITY=STRONG # 密码复杂度要求

3. 企业级 Docker Compose 配置

创建企业级 docker-compose.yml 文件,支持一主多从架构并集成监控、高可用等企业级特性:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
version: '3.8'

# 扩展配置
x-redis-common:
&redis-common
image: redis:7.0-alpine # Redis 7.0 LTS 版本
restart: always
environment:
- TZ=Asia/Shanghai
volumes:
- ./ssl:/etc/redis/ssl
security_opt:
- no-new-privileges:true
networks:
- redis-network

x-redis-healthcheck:
&redis-healthcheck
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_MASTER_PASSWORD}", "ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s

services:
# ==========================================
# Redis 主节点服务
# ==========================================
redis-master:
<<: *redis-common
container_name: redis-master
ports:
- "${REDIS_MASTER_PORT}:6379"
volumes:
- ./data/master:/data
- ./conf/master/master.conf:/usr/local/etc/redis/redis.conf
- ./logs/master:/var/log/redis
- ./ssl:/etc/redis/ssl
command: redis-server /usr/local/etc/redis/redis.conf
resources:
limits:
cpus: '${CONTAINER_MASTER_CPU}'
memory: '${CONTAINER_MASTER_MEMORY}'
reservations:
cpus: '${CONTAINER_MASTER_CPU}'
memory: '${CONTAINER_MASTER_MEMORY}'
<<: *redis-healthcheck
depends_on:
- redis-exporter-master

# ==========================================
# Redis 从节点服务
# ==========================================
redis-slave1:
<<: *redis-common
container_name: redis-slave1
ports:
- "${REDIS_SLAVE1_PORT}:6379"
volumes:
- ./data/slave1:/data
- ./conf/slave/slave.conf:/usr/local/etc/redis/redis.conf
- ./logs/slave1:/var/log/redis
- ./ssl:/etc/redis/ssl
command: redis-server /usr/local/etc/redis/redis.conf --replicaof redis-master 6379
resources:
limits:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
reservations:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
<<: *redis-healthcheck
depends_on:
- redis-master
- redis-exporter-slave1

redis-slave2:
<<: *redis-common
container_name: redis-slave2
ports:
- "${REDIS_SLAVE2_PORT}:6379"
volumes:
- ./data/slave2:/data
- ./conf/slave/slave.conf:/usr/local/etc/redis/redis.conf
- ./logs/slave2:/var/log/redis
- ./ssl:/etc/redis/ssl
command: redis-server /usr/local/etc/redis/redis.conf --replicaof redis-master 6379
resources:
limits:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
reservations:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
<<: *redis-healthcheck
depends_on:
- redis-master
- redis-exporter-slave2

# ==========================================
# Redis 哨兵服务
# ==========================================
redis-sentinel1:
<<: *redis-common
container_name: redis-sentinel1
ports:
- "${REDIS_SENTINEL_PORT1}:26379"
volumes:
- ./data/sentinel1:/data
- ./conf/sentinel/sentinel.conf:/usr/local/etc/redis/sentinel.conf
- ./logs/sentinel:/var/log/redis
- ./ssl:/etc/redis/ssl
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
resources:
limits:
cpus: '${CONTAINER_SENTINEL_CPU}'
memory: '${CONTAINER_SENTINEL_MEMORY}'
reservations:
cpus: '${CONTAINER_SENTINEL_CPU}'
memory: '${CONTAINER_SENTINEL_MEMORY}'
depends_on:
- redis-master
- redis-slave1
- redis-slave2

redis-sentinel2:
<<: *redis-common
container_name: redis-sentinel2
ports:
- "${REDIS_SENTINEL_PORT2}:26379"
volumes:
- ./data/sentinel2:/data
- ./conf/sentinel/sentinel.conf:/usr/local/etc/redis/sentinel.conf
- ./logs/sentinel:/var/log/redis
- ./ssl:/etc/redis/ssl
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
resources:
limits:
cpus: '${CONTAINER_SENTINEL_CPU}'
memory: '${CONTAINER_SENTINEL_MEMORY}'
reservations:
cpus: '${CONTAINER_SENTINEL_CPU}'
memory: '${CONTAINER_SENTINEL_MEMORY}'
depends_on:
- redis-master
- redis-slave1
- redis-slave2

redis-sentinel3:
<<: *redis-common
container_name: redis-sentinel3
ports:
- "${REDIS_SENTINEL_PORT3}:26379"
volumes:
- ./data/sentinel3:/data
- ./conf/sentinel/sentinel.conf:/usr/local/etc/redis/sentinel.conf
- ./logs/sentinel:/var/log/redis
- ./ssl:/etc/redis/ssl
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
resources:
limits:
cpus: '${CONTAINER_SENTINEL_CPU}'
memory: '${CONTAINER_SENTINEL_MEMORY}'
reservations:
cpus: '${CONTAINER_SENTINEL_CPU}'
memory: '${CONTAINER_SENTINEL_MEMORY}'
depends_on:
- redis-master
- redis-slave1
- redis-slave2

# ==========================================
# Redis Exporter 监控服务
# ==========================================
redis-exporter-master:
image: oliver006/redis_exporter:v1.37.0
container_name: redis-exporter-master
ports:
- "9121:9121"
environment:
- REDIS_ADDR=redis://redis-master:6379
- REDIS_PASSWORD=${REDIS_MASTER_PASSWORD}
- REDIS_EXPORTER_LOG_LEVEL=info
- REDIS_EXPORTER_NAMESPACE=redis
restart: always
depends_on:
- redis-master
networks:
- redis-network

redis-exporter-slave1:
image: oliver006/redis_exporter:v1.37.0
container_name: redis-exporter-slave1
ports:
- "9122:9121"
environment:
- REDIS_ADDR=redis://redis-slave1:6379
- REDIS_PASSWORD=${REDIS_SLAVE_PASSWORD}
- REDIS_EXPORTER_LOG_LEVEL=info
- REDIS_EXPORTER_NAMESPACE=redis
restart: always
depends_on:
- redis-slave1
networks:
- redis-network

redis-exporter-slave2:
image: oliver006/redis_exporter:v1.37.0
container_name: redis-exporter-slave2
ports:
- "9123:9121"
environment:
- REDIS_ADDR=redis://redis-slave2:6379
- REDIS_PASSWORD=${REDIS_SLAVE_PASSWORD}
- REDIS_EXPORTER_LOG_LEVEL=info
- REDIS_EXPORTER_NAMESPACE=redis
restart: always
depends_on:
- redis-slave2
networks:
- redis-network

# ==========================================
# 负载均衡服务
# ==========================================
nginx:
image: nginx:1.24-alpine
container_name: redis-lb
ports:
- "${NGINX_PORT}:6379"
volumes:
- ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./logs/nginx:/var/log/nginx
restart: always
healthcheck:
test: ["CMD", "nginx", "-t"]
interval: 30s
timeout: 10s
retries: 3
depends_on:
- redis-slave1
- redis-slave2
networks:
- redis-network

# ==========================================
# 监控服务
# ==========================================
prometheus:
image: prom/prometheus:v2.45.0
container_name: prometheus
volumes:
- ./conf/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./data/prometheus:/prometheus
ports:
- "${PROMETHEUS_PORT}:9090"
restart: always
depends_on:
- redis-exporter-master
- redis-exporter-slave1
- redis-exporter-slave2
networks:
- redis-network

grafana:
image: grafana/grafana:9.5.15
container_name: grafana
volumes:
- ./data/grafana:/var/lib/grafana
- ./conf/grafana/provisioning:/etc/grafana/provisioning
- ./conf/grafana/dashboards:/var/lib/grafana/dashboards
ports:
- "${GRAFANA_PORT}:3000"
restart: always
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
- GF_SERVER_ROOT_URL=http://localhost:${GRAFANA_PORT}
- GF_SERVER_DOMAIN=localhost
depends_on:
- prometheus
networks:
- redis-network

# ==========================================
# 备份服务
# ==========================================
backup:
image: redis:7.0-alpine
container_name: redis-backup
volumes:
- ./backup:/backup
- ./scripts/backup:/scripts
- ./logs/backup:/var/log/redis
environment:
- TZ=Asia/Shanghai
- REDIS_MASTER_PASSWORD=${REDIS_MASTER_PASSWORD}
command: /bin/sh -c "while true; do /scripts/backup.sh; sleep 86400; done"
depends_on:
- redis-master
networks:
- redis-network

# ==========================================
# 网络配置
# ==========================================
networks:
redis-network:
driver: bridge
ipam:
config:
- subnet: ${NETWORK_SUBNET}
gateway: ${NETWORK_GATEWAY}
driver_opts:
com.docker.network.bridge.name: "redis-br"
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
labels:
- "com.docker.network.description=Redis Master-Slave Cluster Network"

3.1 Nginx 负载均衡配置

创建 conf/nginx/nginx.conf 文件:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 用户配置
user nginx;
worker_processes auto;
pid /var/run/nginx.pid;

events {
worker_connections 4096;
multi_accept on;
use epoll;
}

http {
# 基本配置
include /etc/nginx/mime.types;
default_type application/octet-stream;

# 日志配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$upstream_addr" "$upstream_status" "$upstream_response_time"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;

# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 100;

# 上游服务器配置
upstream redis_read {
least_conn;
server redis-slave1:6379 max_fails=3 fail_timeout=30s weight=1;
server redis-slave2:6379 max_fails=3 fail_timeout=30s weight=1;
}

# 主服务器配置
server {
listen 6379;
server_name localhost;

# 健康检查
location /health {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 172.22.0.0/16;
deny all;
}

# Redis 读请求负载均衡
location / {
proxy_pass http://redis_read;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";

# 超时配置
proxy_connect_timeout 10s;
proxy_send_timeout 10s;
proxy_read_timeout 30s;
}
}
}

3.2 Prometheus 监控配置

创建 conf/prometheus/prometheus.yml 文件:

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
55
56
57
58
59
60
61
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'redis-cluster'

# 告警管理
alerting:
alertmanagers:
- static_configs:
- targets: []

# 告警规则
rule_files:
- /etc/prometheus/rules.yml

# 抓取配置
scrape_configs:
# Redis 主节点监控
- job_name: 'redis-master'
static_configs:
- targets: ['redis-exporter-master:9121']
metrics_path: '/metrics'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):9121'
target_label: instance
replacement: '$1'

# Redis 从节点 1 监控
- job_name: 'redis-slave1'
static_configs:
- targets: ['redis-exporter-slave1:9121']
metrics_path: '/metrics'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):9121'
target_label: instance
replacement: '$1'

# Redis 从节点 2 监控
- job_name: 'redis-slave2'
static_configs:
- targets: ['redis-exporter-slave2:9121']
metrics_path: '/metrics'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):9121'
target_label: instance
replacement: '$1'

# Nginx 监控
- job_name: 'nginx'
static_configs:
- targets: ['nginx:6379']
metrics_path: '/health'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):6379'
target_label: instance
replacement: '$1'

4. 企业级部署流程

4.1 部署前验证

4.1.1 环境检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 检查 Docker 版本
docker --version

# 检查 Docker Compose 版本
docker-compose --version

# 检查系统资源
top -bn1 | head -20

# 检查磁盘空间
df -h

# 检查网络连接
ping -c 3 redis.io

# 检查端口占用
netstat -tulpn | grep -E '6379|26379|9090|3000|6389'

4.1.2 配置文件验证

1
2
3
4
5
6
7
8
9
10
11
12
# 检查配置文件语法
docker-compose config

# 验证环境变量文件
ls -la .env
cat .env | grep -v '^#' | grep -v '^$'

# 检查目录结构
find . -type d -name "*master*" -o -name "*slave*" -o -name "*sentinel*" | sort

# 检查配置文件权限
ls -la conf/

4.2 部署执行

4.2.1 启动服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 创建网络
docker network create redis-network || true

# 启动服务
docker-compose up -d

# 等待服务启动
for i in {1..30}; do
if docker-compose ps | grep -E 'redis-master.*Up' && docker-compose ps | grep -E 'redis-slave1.*Up' && docker-compose ps | grep -E 'redis-slave2.*Up'; then
echo "✅ Redis 服务启动成功"
break
fi
echo "⏳ 等待服务启动... ($i/30)"
sleep 2
done

4.2.2 服务状态检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 检查服务状态
docker-compose ps

# 检查容器健康状态
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" ping
docker-compose exec redis-slave1 redis-cli -a "${REDIS_SLAVE_PASSWORD}" ping
docker-compose exec redis-slave2 redis-cli -a "${REDIS_SLAVE_PASSWORD}" ping

# 检查哨兵状态
docker-compose exec redis-sentinel1 redis-cli -p 26379 sentinel master mymaster

# 检查监控服务
docker-compose exec prometheus curl -s localhost:9090/-/healthy
docker-compose exec grafana curl -s localhost:3000/api/health

# 检查负载均衡
docker-compose exec nginx curl -s localhost:6379/health

4.3 部署后验证

4.3.1 主从复制验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 进入主节点容器
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}"

# 在主节点设置测试数据
set test_key "Hello Redis Master-Slave"
get test_key
info replication

# 进入从节点 1 容器
docker-compose exec redis-slave1 redis-cli -a "${REDIS_SLAVE_PASSWORD}"

# 在从节点 1 验证数据同步
get test_key
info replication

# 进入从节点 2 容器
docker-compose exec redis-slave2 redis-cli -a "${REDIS_SLAVE_PASSWORD}"

# 在从节点 2 验证数据同步
get test_key
info replication

4.3.2 哨兵模式验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 查看哨兵状态
docker-compose exec redis-sentinel1 redis-cli -p 26379 sentinel master mymaster
docker-compose exec redis-sentinel1 redis-cli -p 26379 sentinel slaves mymaster

# 模拟主节点故障
docker-compose stop redis-master

# 等待故障转移(约 30-60 秒)
sleep 60

# 检查哨兵状态(应该有新的主节点)
docker-compose exec redis-sentinel1 redis-cli -p 26379 sentinel master mymaster

# 恢复原主节点
docker-compose start redis-master

# 检查主从状态(原主节点应变为从节点)
sleep 30
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" info replication

4.3.3 监控系统验证

1
2
3
4
5
6
7
8
9
10
# 检查 Prometheus 目标
docker-compose exec prometheus curl -s localhost:9090/api/v1/targets

# 检查 Redis 监控指标
docker-compose exec prometheus curl -s "localhost:9090/api/v1/query?query=redis_up"

# 检查 Grafana 仪表盘
echo "访问 Grafana 仪表盘: http://localhost:${GRAFANA_PORT}"
echo "默认用户名: admin"
echo "默认密码: ${GRAFANA_ADMIN_PASSWORD}"

4.3.4 负载均衡验证

1
2
3
4
5
6
# 测试负载均衡
docker-compose exec nginx curl -s "http://localhost:6379/"
echo "测试负载均衡轮询效果:"
for i in {1..5}; do
docker-compose exec nginx curl -s "http://localhost:6379/" | grep -E 'redis-slave'
done

4.3.5 备份服务验证

1
2
3
4
5
6
7
8
# 手动触发备份
docker-compose exec backup /scripts/backup.sh

# 检查备份文件
ls -la backup/

# 验证备份文件大小
du -sh backup/*.rdb

5. 企业级高级配置

5.1 级联复制架构

5.1.1 架构设计

级联复制适用于大规模部署场景,通过引入中间从节点减轻主节点的复制压力:

架构拓扑

  • 主节点(Master) → 中间从节点(Intermediate Slave) → 下层从节点(Leaf Slave)
  • 推荐配置:1 主节点 + 2 中间从节点 + 4-8 下层从节点

5.1.2 配置实现

中间从节点配置conf/intermediate/intermediate.conf):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 基础配置
bind 0.0.0.0
port 6379
daemonize no
dir /data

# 复制配置
replicaof redis-master 6379
replica-read-only yes

# 启用复制传播(关键配置)
replica-serve-stale-data yes

# 其他配置同从节点...

下层从节点配置conf/leaf/leaf.conf):

1
2
3
4
5
6
7
8
9
10
11
# 基础配置
bind 0.0.0.0
port 6379
daemonize no
dir /data

# 指向中间从节点(关键配置)
replicaof redis-intermediate1 6379
replica-read-only yes

# 其他配置同从节点...

Docker Compose 扩展

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
# 中间从节点
redis-intermediate1:
<<: *redis-common
container_name: redis-intermediate1
ports:
- "6382:6379"
volumes:
- ./data/intermediate1:/data
- ./conf/intermediate/intermediate.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
depends_on:
- redis-master

# 下层从节点
redis-leaf1:
<<: *redis-common
container_name: redis-leaf1
ports:
- "6383:6379"
volumes:
- ./data/leaf1:/data
- ./conf/leaf/leaf.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
depends_on:
- redis-intermediate1

5.2 混合云架构

5.2.1 架构设计

本地数据中心

  • 主节点 + 1-2 个从节点
  • 低延迟,高带宽

云环境

  • 1-2 个从节点
  • 跨地域灾备

5.2.2 配置实现

云从节点配置conf/cloud/cloud.conf):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 基础配置
bind 0.0.0.0
port 6379
daemonize no
dir /data

# 复制配置(指向本地主节点公网地址)
replicaof <本地主节点公网IP> 6379
replica-read-only yes

# 网络优化
repl-disable-tcp-nodelay yes # 远距离复制启用 TCP 延迟
repl-timeout 120 # 增加超时时间

# 其他配置同从节点...

网络配置

  • 本地主节点开放 6379 端口到云从节点
  • 建议使用 VPN 或专线连接
  • 配置防火墙规则限制访问源 IP

5.3 多活架构

5.3.1 架构设计

双主架构

  • 两个主节点,双向复制
  • 配合哨兵模式实现自动故障转移

5.3.2 配置实现

主节点 A 配置

1
2
3
4
5
6
7
8
9
10
11
# 基础配置
bind 0.0.0.0
port 6379
daemonize no
dir /data

# 复制配置
replicaof <主节点BIP> 6379
replica-read-only no # 允许写入

# 其他配置...

主节点 B 配置

1
2
3
4
5
6
7
8
9
10
11
# 基础配置
bind 0.0.0.0
port 6379
daemonize no
dir /data

# 复制配置
replicaof <主节点AIP> 6379
replica-read-only no # 允许写入

# 其他配置...

5.4 企业级安全加固

5.4.1 网络隔离

Docker 网络配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
networks:
redis-internal:
driver: bridge
ipam:
config:
- subnet: 172.23.0.0/16
internal: true # 内部网络,不允许外部访问

redis-external:
driver: bridge
ipam:
config:
- subnet: 172.24.0.0/16
# 外部可访问网络

服务网络分配

  • 主从节点:仅加入 redis-internal 网络
  • 哨兵节点:仅加入 redis-internal 网络
  • Nginx 负载均衡:加入 redis-internalredis-external 网络
  • 监控服务:加入 redis-internal 网络

5.4.2 认证与授权

企业级密码策略

  • 密码长度 ≥ 16 位
  • 包含大小写字母、数字、特殊字符
  • 定期轮换密码(每 90 天)
  • 使用环境变量管理密码,避免硬编码

ACL 配置(Redis 6.0+):

1
2
3
4
5
6
7
8
# 启用 ACL
aclfile /etc/redis/users.acl

# 配置文件示例
user default off
user admin on >your-strong-password ~* &* +@all
user app-read on >your-app-password ~* -@write +@read
user app-write on >your-app-password ~* +@all

5.4.3 数据加密

传输加密

1
2
3
4
5
6
7
8
# SSL 配置
ssl-port 6380
ssl-cert-file /etc/redis/ssl/server.crt
ssl-key-file /etc/redis/ssl/server.key
ssl-ca-cert-file /etc/redis/ssl/ca.crt
ssl-protocols TLSv1.2 TLSv1.3
ssl-ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"
ssl-prefer-server-ciphers no

5.5 企业级监控增强

5.5.1 Prometheus 告警规则

创建 conf/prometheus/rules.yml

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
groups:
- name: redis-alerts
rules:
- alert: RedisDown
expr: redis_up == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Redis 实例宕机"
description: "Redis 实例 {{ $labels.instance }} 已宕机超过 5 分钟"

- alert: RedisReplicationLag
expr: redis_replication_offset_delay > 10000
for: 5m
labels:
severity: warning
annotations:
summary: "Redis 复制延迟"
description: "Redis 从节点 {{ $labels.instance }} 复制延迟超过 10000 偏移量"

- alert: RedisMemoryUsage
expr: redis_memory_used_bytes / redis_memory_max_bytes * 100 > 80
for: 10m
labels:
severity: warning
annotations:
summary: "Redis 内存使用率过高"
description: "Redis 实例 {{ $labels.instance }} 内存使用率超过 80%"

- alert: RedisCPUUsage
expr: redis_cpu_used_sys_seconds_total > 1
for: 5m
labels:
severity: warning
annotations:
summary: "Redis CPU 使用率过高"
description: "Redis 实例 {{ $labels.instance }} CPU 使用率过高"

5.5.2 Grafana 企业级仪表盘

推荐仪表盘

  • Redis 官方仪表盘(ID: 763)
  • Redis Cluster 仪表盘(ID: 11835)
  • Linux 服务器监控仪表盘(ID: 1860)

自定义仪表盘配置

  • 主从复制状态面板
  • 哨兵故障转移历史
  • 内存使用趋势
  • 命令执行统计
  • 网络流量监控

5.6 企业级备份策略

5.6.1 多维度备份

全量备份

  • 每日凌晨 2 点执行
  • 保留 7 天
  • 备份到本地和远程存储

增量备份

  • 每小时执行
  • 保留 24 小时
  • 基于 AOF 重写

快照备份

  • 每 6 小时执行
  • 保留 3 天
  • 轻量级备份

5.6.2 备份脚本

创建 scripts/backup/backup.sh

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
#!/bin/bash

# 配置
BACKUP_DIR="/backup"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
REDIS_MASTER_PASSWORD="${REDIS_MASTER_PASSWORD}"
RETENTION_DAYS=7

# 创建备份目录
mkdir -p "${BACKUP_DIR}/full"
mkdir -p "${BACKUP_DIR}/incremental"
mkdir -p "${BACKUP_DIR}/snapshot"

# 全量备份
echo "开始全量备份..."
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" bgsave
while true; do
STATUS=$(docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" info Persistence | grep rdb_bgsave_in_progress | cut -d: -f2)
if [ "${STATUS}" -eq 0 ]; then
break
fi
echo "等待 BGSAVE 完成..."
sleep 1
done

# 复制 RDB 文件
docker cp "$(docker-compose ps -q redis-master):/data/dump.rdb" "${BACKUP_DIR}/full/redis_full_${TIMESTAMP}.rdb"

# 压缩备份
gzip "${BACKUP_DIR}/full/redis_full_${TIMESTAMP}.rdb"

# 清理过期备份
echo "清理 ${RETENTION_DAYS} 天前的备份..."
find "${BACKUP_DIR}/full" -name "*.rdb.gz" -mtime +${RETENTION_DAYS} -delete
find "${BACKUP_DIR}/incremental" -name "*.aof.gz" -mtime +1 -delete
find "${BACKUP_DIR}/snapshot" -name "*.rdb.gz" -mtime +3 -delete

echo "备份完成!"

5.7 企业级灾备方案

5.7.1 本地灾备

  • 热备:从节点实时同步
  • 温备:定时备份到本地存储
  • 冷备:定期备份到离线存储

5.7.2 异地灾备

  • 跨机房:同城市不同机房
  • 跨地域:不同城市
  • 跨云:不同云服务商

5.7.3 灾备演练

定期演练计划

  • 每月进行一次从节点提升为主节点演练
  • 每季度进行一次全流程灾备切换演练
  • 每年进行一次完整的灾难恢复演练

演练步骤

  1. 模拟主节点故障
  2. 触发哨兵故障转移
  3. 验证应用连接切换
  4. 验证数据完整性
  5. 恢复原主节点
  6. 编写演练报告

6. 常见问题与解决方案

6.1 主从复制问题

6.1.1 复制延迟

症状:从节点数据与主节点不同步,复制偏移量差距较大

原因分析

  • 网络带宽不足
  • 主节点写入压力过大
  • 从节点性能不足
  • 复制缓冲区配置不当

解决方案

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 检查网络连接
telnet redis-master 6379

# 2. 调整主节点复制缓冲区大小
# 在主节点配置文件中设置
repl-backlog-size 50mb

# 3. 检查从节点性能
docker stats redis-slave1

# 4. 考虑使用级联复制架构
# 减轻主节点复制压力

6.1.2 复制中断

症状:从节点显示 “master_link_status:down”

原因分析

  • 网络连接中断
  • 主节点密码变更
  • 主节点重启
  • 配置文件错误

解决方案

1
2
3
4
5
6
7
8
9
10
11
# 1. 检查主节点状态
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" ping

# 2. 检查从节点复制状态
docker-compose exec redis-slave1 redis-cli -a "${REDIS_SLAVE_PASSWORD}" info replication

# 3. 重新配置从节点
docker-compose exec redis-slave1 redis-cli -a "${REDIS_SLAVE_PASSWORD}" replicaof redis-master 6379

# 4. 检查密码配置
# 确保 masterauth 与主节点 requirepass 一致

6.2 哨兵模式问题

6.2.1 故障转移失败

症状:主节点故障后,哨兵未成功选举新主节点

原因分析

  • 哨兵集群网络问题
  • 哨兵配置错误
  • 从节点数量不足
  • 从节点优先级配置不当

解决方案

1
2
3
4
5
6
7
8
9
# 1. 检查哨兵状态
docker-compose exec redis-sentinel1 redis-cli -p 26379 sentinel master mymaster

# 2. 检查哨兵日志
docker-compose logs redis-sentinel1

# 3. 确保至少有 2 个哨兵节点正常运行
# 4. 检查从节点优先级配置
# replica-priority 值越小优先级越高

6.2.2 哨兵集群脑裂

症状:哨兵集群分裂成多个子集群,各自选举主节点

原因分析

  • 网络分区
  • 哨兵节点数量不足
  • 超时配置不当

解决方案

1
2
3
4
5
6
# 1. 确保部署至少 3 个哨兵节点
# 2. 调整故障检测阈值
sentinel down-after-milliseconds mymaster 30000

# 3. 配置法定人数
sentinel monitor mymaster redis-master 6379 2 # 需要 2 个哨兵同意

6.3 性能问题

6.3.1 内存使用过高

症状:Redis 内存使用率持续超过 80%

原因分析

  • 数据量增长过快
  • 内存淘汰策略不当
  • 内存碎片率高
  • 大键未及时清理

解决方案

1
2
3
4
5
6
7
8
9
10
11
# 1. 检查内存使用情况
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" info memory

# 2. 查找大键
redis-cli -a "${REDIS_MASTER_PASSWORD}" --bigkeys

# 3. 调整内存淘汰策略
maxmemory-policy allkeys-lru

# 4. 执行内存重分配
docker-compose restart redis-master # 谨慎操作,生产环境建议在维护窗口执行

6.3.2 CPU 使用率过高

症状:Redis 容器 CPU 使用率持续超过 80%

原因分析

  • 命令执行过于频繁
  • 复杂命令执行
  • 网络流量过大
  • 持久化操作频繁

解决方案

1
2
3
4
5
6
7
8
9
10
11
# 1. 检查命令执行统计
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" info commandstats

# 2. 检查慢查询日志
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" slowlog get

# 3. 调整持久化策略
# 降低 AOF 同步频率
appendfsync everysec

# 4. 增加从节点分担读压力

6.4 网络问题

6.4.1 连接超时

症状:客户端连接 Redis 超时

原因分析

  • 网络延迟过高
  • 连接池配置不当
  • Redis 连接数达到上限
  • 防火墙规则限制

解决方案

1
2
3
4
5
6
7
8
9
10
11
# 1. 检查网络延迟
ping redis-master

# 2. 检查 Redis 连接数
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" info clients

# 3. 调整最大连接数
maxclients 10000

# 4. 检查防火墙规则
iptables -L -n

6.4.2 端口占用

症状:启动时端口被占用

原因分析

  • 旧实例未完全停止
  • 其他服务占用端口
  • 容器网络冲突

解决方案

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 检查端口占用
netstat -tulpn | grep 6379

# 2. 停止旧实例
docker-compose down

# 3. 检查容器网络
docker network ls

# 4. 重新创建网络
docker network rm redis-network
docker network create redis-network

7. 监控与维护

7.1 日常维护

7.1.1 健康检查

每日检查

1
2
3
4
5
6
7
8
9
10
11
# 1. 检查所有服务状态
docker-compose ps

# 2. 检查主从复制状态
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" info replication

# 3. 检查哨兵状态
docker-compose exec redis-sentinel1 redis-cli -p 26379 sentinel master mymaster

# 4. 检查监控系统
echo "访问 Grafana: http://localhost:${GRAFANA_PORT}"

7.1.2 日志管理

日志清理

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 检查日志大小
du -sh logs/

# 2. 清理过期日志
find logs/ -name "*.log" -mtime +7 -delete

# 3. 配置日志轮转
# 在 Docker Compose 中设置日志驱动
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

7.2 定期维护

7.2.1 备份验证

每周验证

1
2
3
4
5
6
7
8
# 1. 检查备份文件
sudo ls -la backup/

# 2. 验证备份文件完整性
gunzip -t backup/*.rdb.gz

# 3. 测试恢复流程
# 在测试环境中执行

7.2.2 性能优化

每月优化

1
2
3
4
5
6
7
8
# 1. 分析性能指标
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" info stats

# 2. 调整配置参数
# 根据监控数据调整内存、网络等配置

# 3. 检查大键
docker-compose exec redis-master redis-cli -a "${REDIS_MASTER_PASSWORD}" --bigkeys

7.2.3 版本升级

升级流程

  1. 备份数据:执行全量备份
  2. 测试环境验证:在测试环境验证新版本
  3. 滚动升级:先升级从节点,再升级主节点
  4. 验证服务:检查所有服务正常运行

7.3 监控体系

7.3.1 核心监控指标

必须监控的指标

  • 主从复制:master_link_status、 replication_offset
  • 内存使用:used_memory_rss、mem_fragmentation_ratio
  • CPU 使用率:used_cpu_sys、used_cpu_user
  • 命令执行:instantaneous_ops_per_sec、slowlog_count
  • 网络流量:bytes_received、bytes_sent
  • 客户端连接:connected_clients、blocked_clients

7.3.2 告警配置

关键告警

  • Redis 实例宕机
  • 主从复制中断
  • 内存使用率超过 80%
  • CPU 使用率超过 80%
  • 客户端连接数超过 80%
  • 复制延迟超过 10 秒

8. 性能优化

8.1 系统级优化

8.1.1 Linux 内核调优

优化参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 编辑系统内核参数
sudo nano /etc/sysctl.conf

# 添加以下配置
# 网络优化
net.core.somaxconn = 65535 # 最大连接数
net.ipv4.tcp_max_syn_backlog = 65535 # 最大半连接数
net.ipv4.tcp_fin_timeout = 30 # FIN 超时时间

# 内存管理
vm.swappiness = 10 # 交换空间使用倾向
vm.overcommit_memory = 1 # 内存过度分配策略

# 文件系统
fs.file-max = 655350 # 最大文件描述符

# 应用配置
sudo sysctl -p

8.1.2 Docker 优化

Docker daemon 配置

1
2
3
4
5
6
7
8
9
10
11
{
"default-shm-size": "2g",
"storage-driver": "overlay2",
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 10,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}

8.2 Redis 配置优化

8.2.1 内存配置

最佳实践

1
2
3
4
5
6
7
8
9
10
11
# 内存限制
maxmemory 2gb

# 内存淘汰策略
maxmemory-policy volatile-lru

# 淘汰采样数量
maxmemory-samples 5

# 内存碎片整理
activerehashing yes

8.2.2 持久化优化

最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# RDB 持久化
save 3600 1
save 600 100
save 300 1000
rdbcompression yes
rdbchecksum yes

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

# 混合持久化
aof-use-rdb-preamble yes

8.2.3 网络优化

最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
13
# 绑定地址
bind 0.0.0.0

# 端口
port 6379

# TCP 配置
tcp-keepalive 300
timeout 0

# 复制网络优化
repl-disable-tcp-nodelay no # 局域网使用
# repl-disable-tcp-nodelay yes # 广域网使用

8.2.4 线程优化

最佳实践

1
2
3
4
5
6
7
# IO 线程数(Redis 6.0+)
io-threads 4 # 根据 CPU 核心数调整
io-threads-do-reads yes

# 时钟频率
hz 100
dynamic-hz yes

8.3 应用层优化

8.3.1 连接池配置

Java 应用示例

1
2
3
4
5
6
7
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(100);
poolConfig.setMaxIdle(50);
poolConfig.setMinIdle(10);
poolConfig.setMaxWaitMillis(3000);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);

8.3.2 命令优化

最佳实践

  • 使用管道(Pipeline)批量执行命令
  • 避免使用 O(N) 复杂度的命令
  • 使用哈希表(Hash)存储对象数据
  • 合理使用过期时间
  • 避免在高峰期执行大键操作

8.3.3 数据结构优化

推荐数据结构

  • String:存储简单键值对
  • Hash:存储对象数据
  • List:存储队列、栈等
  • Set:存储唯一值集合
  • Sorted Set:存储有序集合
  • Stream:存储时间序列数据

9. 安全配置

9.1 认证安全

9.1.1 密码配置

最佳实践

1
2
3
4
5
6
7
8
# 主节点密码
requirepass ${REDIS_MASTER_PASSWORD}

# 从节点连接密码
masterauth ${REDIS_MASTER_PASSWORD}

# 哨兵认证
sentinel auth-pass mymaster ${REDIS_MASTER_PASSWORD}

密码管理

  • 使用环境变量存储密码
  • 定期轮换密码(每 90 天)
  • 使用密码管理工具
  • 避免硬编码密码

9.1.2 ACL 配置

Redis 6.0+ 推荐配置

1
2
3
4
5
6
7
8
# 启用 ACL
aclfile /etc/redis/users.acl

# 用户配置示例
user default off
user admin on >strong-admin-password ~* &* +@all
user app-read on >app-read-password ~* -@write +@read
user app-write on >app-write-password ~* +@all

9.2 网络安全

9.2.1 网络隔离

最佳实践

  • 使用 Docker 内部网络
  • 限制容器网络访问
  • 配置防火墙规则
  • 使用 VPN 连接跨地域部署

防火墙配置

1
2
3
4
5
# 只允许特定 IP 访问 Redis
sudo ufw allow from 192.168.1.0/24 to any port 6379

# 禁止其他 IP 访问
sudo ufw deny 6379

9.2.2 SSL 加密

配置示例

1
2
3
4
5
6
# SSL 配置
ssl-port 6380
ssl-cert-file /etc/redis/ssl/server.crt
ssl-key-file /etc/redis/ssl/server.key
ssl-ca-cert-file /etc/redis/ssl/ca.crt
ssl-protocols TLSv1.2 TLSv1.3

证书管理

  • 使用 Let’s Encrypt 或企业 CA 颁发的证书
  • 定期更新证书
  • 配置证书链完整

9.3 操作安全

9.3.1 权限管理

文件权限

1
2
3
4
5
6
7
8
# 配置文件权限
chmod 644 conf/*

# SSL 证书权限
chmod 600 ssl/*

# 备份目录权限
chmod 750 backup/

Docker 权限

  • 使用非 root 用户运行容器
  • 限制容器挂载权限
  • 禁用容器特权模式

9.3.2 审计日志

配置示例

1
2
3
4
5
6
# 启用慢查询日志
slowlog-log-slower-than 10000
slowlog-max-len 128

# 启用命令统计
info commandstats

日志监控

  • 配置日志集中管理
  • 监控异常命令执行
  • 定期审计日志

9.4 漏洞防护

9.4.1 定期安全扫描

推荐工具

  • Redis 安全扫描工具
  • 容器安全扫描工具(如 Trivy)
  • 网络安全扫描工具(如 Nmap)

扫描频率

  • 每周执行一次安全扫描
  • 每次版本更新后扫描
  • 发现新漏洞后立即扫描

9.4.2 漏洞修复

修复流程

  1. 漏洞评估:评估漏洞影响范围
  2. 制定修复方案:确定修复方法
  3. 测试验证:在测试环境验证修复
  4. 生产环境部署:执行修复
  5. 验证修复:确认漏洞已修复

常见漏洞

  • Redis 未授权访问
  • 密码弱口令
  • 网络暴露
  • 版本漏洞

10. 总结

本文详细介绍了企业级 Docker Compose 部署 Redis 主从复制集群的完整方案,包括:

  • 技术架构:深入解析 Redis 主从复制原理,提供企业级架构设计
  • 部署准备:详细的硬件资源规划、系统调优和目录结构设计
  • 配置文件:企业级配置参数和最佳实践
  • Docker Compose 配置:完整的服务编排配置,包含监控、负载均衡和备份
  • 部署流程:详细的部署前验证、执行和验证步骤
  • 高级配置:级联复制、混合云架构、多活架构等企业级特性
  • 常见问题:详细的问题分析和解决方案
  • 监控维护:完整的监控体系和维护流程
  • 性能优化:系统级、配置级和应用级优化策略
  • 安全配置:认证、网络、操作和漏洞防护

通过本文的指导,您可以构建一个稳定、高效、安全的 Redis 主从复制集群,满足企业级应用的高可用性和性能需求。在实际部署中,应根据具体业务场景和资源情况,合理调整配置参数,确保集群的最佳运行状态。