基于docker搭建redis主从

本文详细介绍了Redis主从复制的工作原理和技术细节,包括增量复制、全量复制的过程及触发条件,并提供了一个具体的部署实例。

redis主从

redis主从的运行机制:
  • 当一个 master 实例和一个 slave 实例连接正常时, master 会发送一连串的命令流来保持对 slave 的更新,以便于将自身数据集的改变复制给 slave ,包括客户端的写入、key 的过期或被逐出等等。

  • 当 master 和 slave 之间的连接断开之后,因为网络问题、或者是主从意识到连接超时, slave 重新连接上 master 并会尝试进行部分重同步:这意味着它会尝试只获取在断开连接期间内丢失的命令流。

  • 当无法进行部分重同步时, slave 会请求进行全量重同步。这会涉及到一个更复杂的过程,例如 master 需要创建所有数据的快照,将之发送给 slave ,之后在数据集更改时持续发送命令流到 slave 。

  • 正常情况下,一个全量重同步要求在磁盘上创建一个 RDB 文件,然后将它从磁盘加载进内存,然后 slave以此进行数据同步。

    如果磁盘性能很低的话,这对 master 是一个压力很大的操作。Redis 2.8.18 是第一个支持无磁盘复制的版本。在此设置中,子进程直接发送 RDB 文件给 slave,无需使用磁盘作为中间储存介质。

redis主从复制的特点
  • Redis 使用异步复制,slave 和 master 之间异步地确认处理的数据量
  • slave 可以接受其他 slave 的连接
  • Redis 复制在 master 侧是非阻塞的
  • 复制在 slave 侧大部分也是非阻塞的。当 slave 进行初次同步时,它可以使用旧数据集处理查询请求,假设你在 redis.conf 中配置了让 Redis 这样做的话。否则,你可以配置如果复制流断开, Redis slave 会返回一个 error 给客户端。但是,在初次同步之后,旧数据集必须被删除,同时加载新的数据集。 slave 在这个短暂的时间窗口内(如果数据集很大,会持续较长时间),会阻塞到来的连接请求。自 Redis 4.0 开始,可以配置 Redis 使删除旧数据集的操作在另一个不同的线程中进行,但是,加载新数据集的操作依然需要在主线程中进行并且会阻塞 slave 。
  • 当 master 关闭持久化时,不能保证数据的安全性,不要这么做

redis的主从配置较为简单,只需要在slave中添加主机配置即可,如下通过3个实例来搭建redis的主从环境

三台redis主机信息:
  • **master: ** 172.18.0.9:6379
  • **slave1:**172.18.0.10:6379
  • **slave2:**172.18.0.11:6379
# 分别在主机slave1与slave2的redis配置文件中添加配置
replicaof 172.18.0.9 6379
masterauth "123456"

使用docker-compose启动redis主从程序

 # redis容器
  redis-master:
    image: gongxulei/redis:5.0
    container_name: my-app-redis-master
    stdin_open: true
    tty: true
    privileged: true
    restart: always
    environment:
      TZ: "Asia/Shanghai"
      LANG: "C.UTF-8"
    ports:
      - "6390:6379"
    volumes:
      - "/Users/gongxulei/docker/redis/master/conf:/usr/local/redis/conf"
      - "/Users/gongxulei/docker/redis/master/logs:/usr/local/redis/logs"
      - "/Users/gongxulei/docker/redis/master/db:/usr/local/redis/db"
    command: ["/root/redis_start.sh"]
    networks:
      default:
        ipv4_address: 172.18.0.9
  # redis-slave1容器
  redis-slave1:
    image: gongxulei/redis:5.0
    container_name: my-app-redis-slave1
    stdin_open: true
    tty: true
    privileged: true
    restart: always
    depends_on:
      - redis-master
    environment:
      TZ: "Asia/Shanghai"
      LANG: "C.UTF-8"
    links:
      - "redis-master"
    ports:
      - "6391:6379"
    volumes:
      - "/Users/gongxulei/docker/redis/slave1/conf:/usr/local/redis/conf"
      - "/Users/gongxulei/docker/redis/slave1/logs:/usr/local/redis/logs"
      - "/Users/gongxulei/docker/redis/slave1/db:/usr/local/redis/db"
    command: ["/root/redis_start.sh"]
    networks:
      default:
        ipv4_address: 172.18.0.10
  # redis-slave1容器
  redis-slave2:
    image: gongxulei/redis:5.0
    container_name: my-app-redis-slave2
    stdin_open: true
    tty: true
    privileged: true
    restart: always
    depends_on:
      - redis-master
    environment:
      TZ: "Asia/Shanghai"
      LANG: "C.UTF-8"
    links:
      - "redis-master"
    ports:
      - "6392:6379"
    volumes:
      - "/Users/gongxulei/docker/redis/slave2/conf:/usr/local/redis/conf"
      - "/Users/gongxulei/docker/redis/slave2/logs:/usr/local/redis/logs"
      - "/Users/gongxulei/docker/redis/slave2/db:/usr/local/redis/db"
    command: ["/root/redis_start.sh"]	
    networks:
      default:
        ipv4_address: 172.18.0.11


查询主从信息:可以看到两台slave主机已处于在线状态

master:0>info replication
"# Replication
role:master
connected_slaves:2
slave0:ip=172.18.0.10,port=6379,state=online,offset=668175,lag=1
slave1:ip=172.18.0.11,port=6379,state=online,offset=668175,lag=1
master_replid:86d7b43cfbbea36962cf5a9e6b580d164031d848
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:668583
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:668583
masterslave1172.18.0.9:6379172.18.0.10:6379Connecting to MASTER 172.18.0.9:6379使用 PSYNC命令发送 Replication ID, offset增量复制:master 能够仅发送 slave 所需的增量部分这两种情况会使得slave进行全量复制:(1)master 的缓冲区中没有足够的命令积压缓冲记(2)slave1引用了未知的历史记录(replication ID)全量复制(1)开启一个后台进程产生一个存储快照RDB文件 (2)同时开始缓冲所有从客户端接收到的新的写入命令master将生成的RDB快照文件传输给slave,slave将之保存在磁盘上,然后加载文件到内存master将所有缓冲的命令发送给slavemasterslave1**redis主从复制原理图**

redis主从并不是一种高可用方案,如果master挂了之后如何自动切换slave为master这种高可用方法需要用到redis Sentinel技术

<think>我们之前已经整理过详细的Docker搭建Redis主从的步骤,用户再次询问可能是想确认或补充细节。根据用户提供的引用资料,特别是引用[1][2][3]中的方法,结合最佳实践,重新整理如下: ### 关键点确认: 1. **目录结构**:每个Redis实例使用独立目录存放配置和数据(如主节点6379,从节点6380/6381)[^2][^3] 2. **配置文件**:主节点无需特殊配置,从节点需设置`replicaof`指向主节点[^3] 3. **容器互联**:使用`--link`或自定义网络确保主从容器互通[^1][^3] 4. **密码一致**:若设置密码,主节点的`requirepass`和从节点的`masterauth`需相同[^3] ### 详细步骤: --- ### 一、创建目录和配置文件 ```bash # 主节点目录(端口6379) mkdir -p /home/docker/redis6379/{conf,data} # 从节点目录(示例6380/6381) mkdir -p /home/docker/redis6380/{conf,data} mkdir -p /home/docker/redis6381/{conf,data} ``` 1. **主节点配置** (`/home/docker/redis6379/conf/redis.conf`) ```conf port 6379 daemonize no # 可选密码设置(若需密码) requirepass 123456 appendonly yes ``` 2. **从节点配置** (`/home/docker/redis6380/conf/redis.conf`) ```conf port 6380 daemonize no # 指向主节点(使用容器名或IP) replicaof redis-master 6379 # 主节点密码(若设置) masterauth 123456 appendonly yes ``` > 📌 注意:Redis 5.0+ 使用 `replicaof` 替代旧版 `slaveof`[^3]。 --- ### 二、启动Redis容器 1. **启动主节点容器** ```bash docker run -d --name redis-master \ -p 6379:6379 \ -v /home/docker/redis6379/conf:/usr/local/etc/redis \ -v /home/docker/redis6379/data:/data \ redis:latest \ redis-server /usr/local/etc/redis/redis.conf ``` 2. **启动从节点容器(6380)** ```bash docker run -d --name redis-slave-6380 \ -p 6380:6380 \ -v /home/docker/redis6380/conf:/usr/local/etc/redis \ -v /home/docker/redis6380/data:/data \ --link redis-master:redis-master \ # 关键!容器网络互联 redis:latest \ redis-server /usr/local/etc/redis/redis.conf ``` 3. **启动第二个从节点(6381)** 重复步骤2,修改端口和目录即可: ```bash docker run -d --name redis-slave-6381 \ -p 6381:6381 \ -v /home/docker/redis6381/conf:/usr/local/etc/redis \ -v /home/docker/redis6381/data:/data \ --link redis-master:redis-master \ redis:latest \ redis-server /usr/local/etc/redis/redis.conf ``` --- ### 三、验证主从复制 1. **查看主节点状态** ```bash docker exec -it redis-master redis-cli 127.0.0.1:6379> AUTH 123456 # 若设置密码 OK 127.0.0.1:6379> INFO replication ``` 输出应包含: ```bash role:master connected_slaves:2 # 显示连接的从节点数 ``` 2. **查看从节点状态** ```bash docker exec -it redis-slave-6380 redis-cli -p 6380 127.0.0.1:6380> AUTH 123456 OK 127.0.0.1:6380> INFO replication ``` 输出应包含: ```bash role:slave master_host:redis-master # 验证主节点连接 master_port:6379 ``` --- ### 四、常见问题解决 | 问题现象 | 解决方法 | |--------------------------|--------------------------------------------------------------------------| | 从节点无法连接主节点 | 1. 检查`--link`或自定义网络<br>2. 确认`replicaof`配置的IP/容器名正确[^1] | | 主从密码验证失败 | 确保主节点`requirepass`和从节点`masterauth`完全一致[^3] | | 配置文件未生效 | 检查`docker run`中`-v`挂载路径是否正确 | | 从节点数据不同步 | 检查主节点日志:`docker logs redis-master` | --- ### 进阶建议 1. **使用Docker Compose部署**:简化多容器管理[^1] 2. **启用持久化**:配置文件设置`appendonly yes`避免数据丢失 3. **哨兵模式**:通过Sentinel实现自动故障转移(生产环境推荐) --- ### 相关问题 1. 如何用Docker Compose一键部署Redis主从集群? 2. Redis主从复制延迟高的原因及优化方法? 3. 如何配置Redis Sentinel实现高可用? 4. DockerRedis数据备份与恢复的最佳实践? [^1]: 容器互联配置与Compose方案 [^2]: 目录结构与配置文件规范 [^3]: 主从密码验证与命令兼容性 </think>以下是使用Docker搭建Redis主从集群的详细步骤,结合容器化部署最佳实践和参考资料整理: --- ### 一、环境准备 #### 1. 创建配置文件目录 ```bash # 主节点目录(端口6379) mkdir -p /home/docker/redis6379/{conf,data} # 从节点目录(示例:6380/6381) mkdir -p /home/docker/redis6380/{conf,data} mkdir -p /home/docker/redis6381/{conf,data} ``` #### 2. 编写配置文件 - **主节点配置**(`/home/docker/redis6379/conf/redis.conf`) ```conf port 6379 daemonize no requirepass 123456 # 主节点密码 masterauth 123456 # 从节点访问主节点的密码 appendonly yes # 开启持久化 ``` - **从节点配置**(`/home/docker/redis6380/conf/redis.conf`) ```conf port 6380 daemonize no replicaof redis-master 6379 # 指向主节点 masterauth 123456 # 主节点密码 requirepass 123456 # 从节点密码(与主节点一致) appendonly yes ``` > 📌 **注意**:Redis 5.0+版本使用`replicaof`,旧版用`slaveof`[^3] --- ### 二、启动Redis容器 #### 1. 启动主节点 ```bash docker run -d --name redis-master \ -p 6379:6379 \ -v /home/docker/redis6379/conf:/usr/local/etc/redis \ -v /home/docker/redis6379/data:/data \ redis:latest \ redis-server /usr/local/etc/redis/redis.conf ``` #### 2. 启动从节点(以6380为例) ```bash docker run -d --name redis-slave-6380 \ -p 6380:6380 \ -v /home/docker/redis6380/conf:/usr/local/etc/redis \ -v /home/docker/redis6380/data:/data \ --link redis-master:redis-master \ # 容器网络互联 redis:latest \ redis-server /usr/local/etc/redis/redis.conf ``` > ✅ 重复此命令启动其他从节点(如6381),修改端口和目录即可[^2][^3] --- ### 三、验证主从复制 #### 1. 检查主节点状态 ```bash docker exec -it redis-master redis-cli -a 123456 127.0.0.1:6379> INFO replication ``` 输出关键信息: ```bash role:master connected_slaves:2 # 连接的从节点数量 slave0:ip=172.17.0.3,port=6380,state=online # 从节点详情 ``` #### 2. 检查从节点状态 ```bash docker exec -it redis-slave-6380 redis-cli -a 123456 -p 6380 127.0.0.1:6380> INFO replication ``` 输出关键信息: ```bash role:slave master_host:redis-master # 正确指向主节点 master_port:6379 master_link_status:up # 连接状态正常 ``` --- ### 四、常见问题解决 | 问题现象 | 解决方法 | |--------------------------|--------------------------------------------------------------------------| | **从节点无法连接主节点** | 1. 检查`--link`或自定义网络<br>2. 确认`masterauth`与主节点`requirepass`一致[^3] | | **配置文件未生效** | 检查`docker run`中`-v`挂载路径是否正确 | | **主从数据不同步** | 1. 检查主节点日志:`docker logs redis-master`<br>2. 确认`replicaof`参数正确 | | **权限问题** | 运行`chmod -R 755 /home/docker/redis*`设置目录权限 | --- ### 五、生产环境建议 1. **密码安全**:使用强密码替换`123456`,主从节点密码需完全一致 2. **持久化配置**:确保所有节点开启`appendonly yes`防止数据丢失 3. **自定义网络**:替代`--link`(已废弃): ```bash docker network create redis-net docker run ... --network redis-net ``` 4. **哨兵模式**:通过Sentinel实现自动故障转移(高可用方案) --- ### 相关问题 1. 如何用Docker Compose一键部署Redis主从集群? 2. Redis主从复制延迟高的原因及优化方法? 3. 如何配置Redis Sentinel实现自动故障转移? 4. DockerRedis数据备份与恢复的最佳实践? [^1]: 容器网络互联与目录挂载配置 [^2]: 配置文件规范与多节点管理 [^3]: 主从密码验证与连接故障排查
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值