想了解 Redis Cluster 的分片、主从复制和客户端重定向,可以先用 Docker Compose 在一台机器上启动六个节点。本文参考 SHOOTER 的集群搭建文章选题,重新组织配置与操作步骤,使用三主三从拓扑完成一个本机实验。
一、实验环境与节点规划
下面的命令在 Linux Bash 中执行,需要 Docker Engine、Docker Compose 插件和 OpenSSL。开始前确认 7000—7005、17000—17005 端口未被占用,并使用一个全新的目录,避免覆盖已有配置。
六个节点使用 7000—7005 作为客户端端口,对应的集群总线端口为 17000—17005。创建集群后,由工具分配主从关系;不要预先认定某个固定端口一定是主节点。Redis Cluster 通过 16384 个哈希槽分布数据,本例为每个主节点配置一个副本。参见 Redis Cluster 官方说明。
本文采用 host 网络,各容器共享宿主机网络,因此节点端口必须不同,也无需配置 ports 映射。这里限定为 Linux Docker Engine;Docker Desktop 的 host 网络需要单独启用,不能照搬默认网络设置。参见 Docker host 网络文档。
适用范围:节点只监听 127.0.0.1,供宿主机及使用同一 host 网络的实验容器访问。其他电脑和普通 bridge 网络容器不能按这些地址连接。六个节点都在一台机器上,宿主机故障会让整个集群停止;该配置不代表跨服务器高可用。
二、生成六份 Redis 配置
按顺序执行下面的命令。随机密码会写入 .env,并同步写入六份 redis.conf。此步骤仅用于首次初始化,恢复已有集群时保留原密码和配置,直接启动即可。
umask 077
mkdir redis-cluster-demo && cd redis-cluster-demo || exit 1
REDIS_PASSWORD="$(openssl rand -hex 32)" || exit 1
printf 'REDIS_PASSWORD=%s\n' "$REDIS_PASSWORD" > .env
for port in 7000 7001 7002 7003 7004 7005; do
mkdir -p "redis-$port"
cat > "redis-$port/redis.conf" <<EOF
bind 127.0.0.1
protected-mode yes
port $port
dir /data
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 127.0.0.1
cluster-announce-port $port
cluster-announce-bus-port $((port + 10000))
appendonly yes
appendfsync everysec
requirepass $REDIS_PASSWORD
masterauth $REDIS_PASSWORD
EOF
chmod 644 "redis-$port/redis.conf"
done新建目录和 .env 使用受限权限;redis.conf 设为可读,方便容器内 Redis 进程加载,父目录仍限制其他本机用户访问。不要将 .env 或包含密码的配置提交到公开仓库。
requirepass 用于客户端认证,masterauth 用于副本连接主节点,六个节点使用相同密码。实验中保留 protected-mode,并绑定回环地址;需要远程接入时,应另外设计内网地址、访问控制与 TLS。密码认证不能替代网络隔离,也不会加密连接。参见 Redis 安全文档。
dir /data 将数据写入挂载卷;nodes.conf 是 Redis 自动维护的集群状态文件,勿手工编辑。appendonly 开启 AOF,appendfsync everysec 使用每秒刷盘策略,仍存在故障时丢失近期写入的窗口。参见 Redis 持久化文档。
三、编写 compose.yaml
在 redis-cluster-demo 目录下新建 compose.yaml,内容如下。公共配置通过 YAML 锚点复用,每个服务分别挂载自己的配置文件和数据卷。
name: redis-cluster-demo
x-redis: &redis
image: redis:7.4-alpine
restart: unless-stopped
network_mode: host
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
environment:
REDISCLI_AUTH: ${REDIS_PASSWORD:?请先创建 .env 文件}
services:
redis-7000:
<<: *redis
volumes:
- ./redis-7000/redis.conf:/usr/local/etc/redis/redis.conf:ro
- data-7000:/data
redis-7001:
<<: *redis
volumes:
- ./redis-7001/redis.conf:/usr/local/etc/redis/redis.conf:ro
- data-7001:/data
redis-7002:
<<: *redis
volumes:
- ./redis-7002/redis.conf:/usr/local/etc/redis/redis.conf:ro
- data-7002:/data
redis-7003:
<<: *redis
volumes:
- ./redis-7003/redis.conf:/usr/local/etc/redis/redis.conf:ro
- data-7003:/data
redis-7004:
<<: *redis
volumes:
- ./redis-7004/redis.conf:/usr/local/etc/redis/redis.conf:ro
- data-7004:/data
redis-7005:
<<: *redis
volumes:
- ./redis-7005/redis.conf:/usr/local/etc/redis/redis.conf:ro
- data-7005:/data
volumes:
data-7000:
data-7001:
data-7002:
data-7003:
data-7004:
data-7005:示例选择 redis:7.4-alpine 作为版本系列,镜像标签可在 Docker 官方 Redis 镜像清单核对。这个标签可能随补丁更新;需要复现实验时记录拉取的镜像 digest。
REDISCLI_AUTH 只负责让容器内 redis-cli 读取认证密码,服务端密码仍由 redis.conf 设置。Docker 管理权限持有者可查看容器环境与配置,请按敏感文件管理。Compose 字段说明见 Docker Compose 服务文档。
四、启动节点并创建集群
先检查 Compose 配置,再启动容器:
docker compose config --quiet
docker compose up -d
docker compose ps
docker compose exec redis-7000 redis-cli -p 7000 PINGPING 预期返回 PONG。如果节点没有正常启动,先检查日志,不要直接初始化集群:
docker compose logs --tail=100 redis-7000六个节点均启动后,执行一次集群创建命令:
docker compose exec redis-7000 redis-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1工具会展示槽位及主从分配方案,检查后输入 yes。成功时应提示所有 16384 个槽位已覆盖。--cluster-replicas 1 表示每个主节点配置一个副本。此命令只适用于尚未加入集群的空节点,已有数据卷重启时无需再次创建。
五、检查状态并验证读写
docker compose exec redis-7000 redis-cli -p 7000 CLUSTER INFO
docker compose exec redis-7000 redis-cli -p 7000 CLUSTER NODES
docker compose exec redis-7000 redis-cli --cluster check 127.0.0.1:7000正常情况下,应看到以下关键状态。下面是预期值,具体 epoch、节点 ID 和主从端口以实际输出为准:
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3cluster_known_nodes 表示已知节点数;cluster_size 表示至少负责一个槽位的主节点数。本例预期分别为 6 和 3。字段含义见 CLUSTER INFO 文档。
使用支持重定向的 -c 模式写入、读取一个键:
docker compose exec redis-7000 redis-cli -c -p 7000 SET demo:message "hello redis cluster"
docker compose exec redis-7000 redis-cli -c -p 7000 GET demo:messageSET 预期返回 OK,GET 预期返回 hello redis cluster。键可能属于其他节点负责的槽位,redis-cli 会自动跟随重定向;未开启 -c 时可能看到 MOVED。认证环境变量与 -c 的说明见 Redis CLI 官方文档。
六、常见问题与日常操作
NOAUTH 或 WRONGPASS:检查 .env、所有节点的 requirepass/masterauth 是否一致。修改 .env 后,要重新创建容器才能更新其环境变量。
Address already in use:检查客户端端口和总线端口,host 网络下任何宿主机进程都可能占用它们。
创建集群提示节点不为空:检查是否复用了已有数据卷、节点是否已经入群。不要通过删除数据来绕过错误。
一直处于 fail:结合日志、CLUSTER NODES 和 --cluster check 检查节点连通性与槽位覆盖,勿仅凭容器显示 running 判断集群健康。
停止并再次启动,可使用:
docker compose down
docker compose up -d普通 down 保留本文使用的命名数据卷,节点恢复时会读取原有状态。不要给 down 添加 -v,否则会删除数据卷。密码、配置和卷应一起保留;备份需求不能由副本或 AOF 设置替代。
本文依据官方文档整理,提供的是实验步骤与预期结果,未附作者实际部署记录。正式环境还需要独立规划节点分布、资源限制、监控和备份,并验证所用客户端对 Redis Cluster 的支持。
一起聊聊
留下你的想法,评论审核通过后展示。