Mac端使用Docker部署Redis 主从复制踩坑实录:别再被 localhost 坑了

最近我在本地用 Docker 搭了个 Redis 主从 + Sentinel 的测试环境。主节点配好了,两个从节点也按照文档配置上了 slaveof localhost 7001,看起来一切正常。

但奇怪的是,主节点始终显示:


connected_slaves:0

也就是说,两个从节点压根没连上来。

我查日志、试连接、重启服务……折腾了一两个小时,最后才发现问题出在一个看似无关紧要的细节上:localhost 和 127.0.0.1 其实不一样!


🧩 到底发生了什么?

在 Linux 系统中,localhost 和 127.0.0.1 通常是一样的,都指向本机。但在 Docker 容器里,尤其是在 macOS 上使用 Docker Desktop 的时候,这个规则就不灵了。

如果你用了 network_mode: host,你以为容器和宿主机共享网络,访问 localhost 就能访问别的容器的服务。但实际上,在 macOS 的 Docker 中,localhost 是指向宿主机本身的,而不是其他容器。

所以当你在从节点里配置:


--slaveof localhost 7001

它其实是去宿主机找 7001 端口有没有 Redis 在运行 —— 而不是去找另一个容器里的 Redis 主节点!

这就导致了从节点一直连不上主节点,主节点也就看不到任何从节点。


✅ 解决方法

把所有的 slaveof localhost 7001 改成:


--slaveof 127.0.0.1 7001

这样,Redis 容器之间就能正确通信了,从节点也能顺利连接上主节点。


🧪 我是怎么验证的?

改完配置后,我执行了下面几步来确认:

  1. 进入从节点容器内部测试连接主节点:

docker exec -it r2 redis-cli -p 7001 ping

返回:


PONG

说明网络是通的。

  1. 查看从节点复制状态:

docker exec -it r2 redis-cli -p 7002 info replication

返回片段如下:


master_link_status:up slave_repl_offset:12345

说明已经成功建立复制链路。

  1. 回到主节点查看从节点数量:

docker exec -it r1 redis-cli -p 7001 info replication

输出:


connected_slaves:2 slave0:ip=127.0.0.1,port=7002,state=online slave1:ip=127.0.0.1,port=7003,state=online

✅ 成功识别两个从节点!


📄 推荐的完整 docker-compose.yaml 配置

以下是优化后的 docker-compose.yaml 文件,包含主节点、两个从节点和三个 Sentinel 节点的完整配置,确保服务间通过 127.0.0.1 正确通信。


services: r1: image: redis:8.0.2 container_name: r1 network_mode: "host" entrypoint: [ "redis-server", "--port", "7001", "--bind", "0.0.0.0", "--protected-mode", "no" ] r2: image: redis:8.0.2 container_name: r2 network_mode: "host" entrypoint: [ "redis-server", "--port", "7002", "--slaveof", "127.0.0.1", "7001", "--bind", "0.0.0.0" ] r3: image: redis:8.0.2 container_name: r3 network_mode: "host" entrypoint: [ "redis-server", "--port", "7003", "--slaveof", "127.0.0.1", "7001", "--bind", "0.0.0.0" ] s1: image: redis:8.0.2 container_name: s1 network_mode: "host" volumes: - ./sentinel/s1:/etc/redis entrypoint: [ "redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27001" ] s2: image: redis:8.0.2 container_name: s2 network_mode: "host" volumes: - ./sentinel/s2:/etc/redis entrypoint: [ "redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27002" ] s3: image: redis:8.0.2 container_name: s3 network_mode: "host" volumes: - ./sentinel/s3:/etc/redis entrypoint: [ "redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27003" ]

💡 提示:你也可以将 slaveof 写入 redis.conf 并挂载进容器,以实现更稳定的主从配置。


📌 总结一下

  • localhost 和 127.0.0.1 不总是等价的,特别是在 Docker 容器环境下。
  • 如果你用的是 macOS 的 Docker Desktop,或者不确定平台行为,请统一使用 127.0.0.1 来做服务间通信
  • 使用 docker-compose 配置 Redis 主从时,虽然可以用 --slaveof 参数设置从属关系,但这不会写入配置文件,容易重启后失效。建议挂载 redis.conf 文件并写入 slaveof 127.0.0.1 <port>,确保稳定生效。
使用Docker部署Redis主从复制可按以下步骤进行: ### 拉取Redis镜像 使用`docker pull`命令拉取Redis镜像: ```bash docker pull redis ``` ### 创建主节点挂载目录 创建主节点需要挂载的Redis目录: ```bash mkdir -p /home/docker/redis6379/conf mkdir -p /home/docker/redis6379/data ``` ### 部署主服务器 #### 修改配置 可根据需求修改主节点的配置文件,配置文件可挂载到容器内。例如使用如下命令启动主节点容器: ```bash docker run -itd --name redis-master -v /usr/local/redis/redis.conf:/etc/redis.conf -v /root/usr/local/redis/data:/data --net mynetwork -p 6380:6379 --ip 172.10.0.2 redis ``` 这里将本地的配置文件和数据目录挂载到容器内,同时指定了网络和口映射等信息 [^5]。 ### 部署从节点 从节点是只读的,配置`slave-read-only yes`,就算写入了从节点,主节点在复制的时候也会把从节点覆盖掉。可通过类似如下命令启动从节点容器: ```bash docker run --name redis-docker -v $PWD/data:/data -v $PWD/conf:/usr/local/etc/redis -p port:6379 -d redis:tag redis-server /usr/local/etc/redis/redis.conf ``` 需要在从节点的配置文件中配置其为主节点的从节点。 ### 测试 #### 主节点写入 ```bash docker exec -it redis-master /bin/sh redis-cli -a abc123 get a set a 123 get a ``` #### 从节点读取 ```bash # slave1读 docker exec -it redis-slave1 /bin/sh redis-cli -a 123456 get a # slave2读 docker exec -it redis-slave2 /bin/sh redis-cli -a 123456 get a ``` ### 注意事项 - 主从复制采取一种主从节点分担Redis读写工作的模式,主节点以写为主,从节点以读为主 ,而且一个主节点可以拥有多个从节点,既能避免Redis单点故障,也可以做到主从分离,满足读多写少的应用场景 [^1]。 - 从节点是只读的,配置`slave-read-only yes`,主节点复制时会覆盖从节点写入的数据 [^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值