使用 Bitnami 镜像快速部署 Redis 主从集群

使用 Bitnami 镜像快速部署 Redis 主从集群

_

在使用 Docker 构建高可用的后端基础架构时,Redis 主从复制(Master-Slave)是最基础也是最常用的模式之一。相较于官方原生镜像,bitnami/redis 提供了开箱即用的集群环境变量配置,非常适合快速搭建。

本文记录了在单台 Ubuntu 虚拟机上,通过自定义 Docker 网络实现 Redis 主从集群部署的全过程,并复盘了一个非常经典的挂载目录权限踩坑案例。

一、 🚀 集群部署命令

为了让主从节点能够互相通信,这里使用了自定义网络 mynet

1. 部署主节点 (Master)

主节点的配置相对简单,主要定义对外端口、持久化挂载目录以及运行模式。

docker run -d --name redis01 \
  -p 6379:6379 \
  -v /app/rd1:/bitnami/redis/data \
  -e REDIS_REPLICATION_MODE=master \
  -e REDIS_PASSWORD=123456 \
  --network mynet \
  bitnami/redis

核心参数解析:

  • REDIS_REPLICATION_MODE=master:明确指定当前容器为主节点。

  • REDIS_PASSWORD:设置 Redis 的访问密码。

2. 部署从节点 (Slave)

从节点需要明确指向主节点的地址和认证信息。

docker run -d --name redis02 \
  -p 6380:6379 \
  --network mynet \
  -v /app/rd2:/bitnami/redis/data \
  -e REDIS_REPLICATION_MODE=slave \
  -e REDIS_MASTER_HOST=redis01 \
  -e REDIS_MASTER_PORT_NUMBER=6379 \
  -e REDIS_MASTER_PASSWORD=123456 \
  -e REDIS_PASSWORD=123456 \
  bitnami/redis

核心参数解析:

  • REDIS_REPLICATION_MODE=slave:指定为从节点模式。

  • REDIS_MASTER_HOST=redis01:利用 Docker 内部的 DNS 解析,直接使用主节点的容器名 redis01 作为主机地址。

  • REDIS_MASTER_PASSWORD:连接主节点进行数据同步时所需的认证密码。

二、 💥 经典踩坑:目录权限被拒绝 (Permission Denied)

1. 报错现象

在执行完上述 run 命令后,容器可能并没有如期运行。通过 docker logs redis01 查看日志,发现了致命错误:

1:M 10 Jun 2026 08:04:23.053 # Can't open or create append-only dir appendonlydir: Permission denied

2. 原因分析

这是使用 bitnami 镜像时非常容易遇到的问题。出于安全考虑,Bitnami 的容器默认使用非 root 用户(通常是 uid 1001)来运行服务进程。 当我们将宿主机的 /app/rd1 目录通过 -v 挂载到容器内的 /bitnami/redis/data 时,宿主机目录的默认所有者通常是 root,导致容器内的非 root 用户没有写入权限,AOF 持久化文件无法创建,服务随即崩溃重启。

3. 解决方案

最直接的修复方式是在宿主机上放开挂载目录的权限,确保容器内进程可读可写:

# 修改主从节点对应的数据挂载目录权限
chmod -R 777 /app/rd1
chmod -R 777 /app/rd2

💡 进阶建议:在生产环境中,出于严格的安全考量,建议使用 chown -R 1001:1001 /app/rd1 将目录所有者精准转移给容器内的对应用户,而不是简单粗暴地放开 777 权限。

三、 ✅ 验证集群状态

权限修复完毕后,重新启动容器。使用 docker ps 查看当前的运行状态,可以看到两个节点均已稳定运行,端口映射也符合预期:

root@loe-virtual-machine:/app# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                         NAMES
be702f9e3f0e   bitnami/redis            "/opt/bitnami/script…"   8 minutes ago    Up 8 minutes    0.0.0.0:6380->6379/tcp, [::]:6380->6379/tcp   redis02
cd4fb0f22667   bitnami/redis            "/opt/bitnami/script…"   29 minutes ago   Up 22 minutes   0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp   redis01

四、 🔍 深度复盘:Redis 从节点全量同步日志剖析

判断 Redis 主从是否真正连接成功,不能只看 Up 状态,我们需要通过 docker logs redis02 深入观察从节点的底层启动和同步日志。

以下是标准的 Redis 主从全量同步 黄金日志及其四阶段拆解:

🤝 阶段 1:建立网络连接与握手

1:S 10 Jun 2026 08:25:21.897 * Connecting to MASTER redis01:6379
1:S 10 Jun 2026 08:25:21.898 * MASTER <-> REPLICA sync started
1:S 10 Jun 2026 08:25:21.898 * Master replied to PING, replication can continue...
  • 剖析:从节点通过自定义网络 mynet 主动拨通主节点 redis01 的 6379 端口。向主节点发送 PING 探测,并成功收到主节点的响应,这意味着主从网络畅通、认证凭证正确

🔄 阶段 2:协商同步策略(触发全量同步)

1:S 10 Jun 2026 08:25:21.898 * Partial resynchronization not possible (no cached master)
1:S 10 Jun 2026 08:25:21.899 * PSYNC is not possible, initialize RDB channel.
  • 剖析:从节点尝试申请“增量同步(Partial resynchronization)”,但由于这是它第一次连接该主节点,本地没有缓存主节点的运行 ID(runid)。Redis 底层随即决定转为全量同步,开始初始化 RDB 数据通道。

📥 阶段 3:接收并加载主节点 RDB 快照

1:S 10 Jun 2026 08:25:26.014 * Starting to receive RDB and replication stream in parallel.
1:S 10 Jun 2026 08:25:26.024 * MASTER <-> REPLICA sync: receiving streamed RDB from master with EOF to disk
1:S 10 Jun 2026 08:25:26.028 * MASTER <-> REPLICA sync: Loading DB in memory
1:S 10 Jun 2026 08:25:26.030 * MASTER <-> REPLICA sync: Flushing old data
  • 剖析:主节点在后台生成了一份最新的 RDB 快照并通过网络流发送给从节点。从节点收到后,首先清空本地老数据(Flushing old data),随后将这份 RDB 加载到内存中(Loading DB in memory)。由于是全新部署,显示 keys loaded: 0

🎉 阶段 4:同步大获成功

1:S 10 Jun 2026 08:25:26.031 * MASTER <-> REPLICA sync: Finished with success
  • 剖析:当在日志中看到 Finished with success 时,说明底层主从数据通道已彻底就绪!后续主节点所有的增量写入修改,都会通过 replication stream 实时广播并同步给该从节点。

📝 博主总结

  1. 安全意识第一步:Bitnami 镜像默认以普通用户运行虽会带来权限摩擦,但更符合企业生产环境的安全规范。挂载宿主机目录时一定要注意 UID 的权限转移。

  2. 拒绝盲目猜测:遇到容器莫名重启或数据不一致,永远第一时间执行 docker logs <容器名>。看懂日志的这四个阶段,是后端开发从“命令调用者”蜕变为“架构理解者”的关键。

至此,一个轻量级的 Redis 主从集群就已经成功跑通了。数据的写入操作将由 redis01 承担,并自动同步到 redis02,为后续的读写分离打下了基础。

Docker 核心命令实战手册:从零到云端分发 2026-06-10
如何把打包好的 Java Jar 包做成 Docker 镜像 2026-06-11

评论区