Redis 主从复制
1. 基本介绍
官网: https://redis.io/docs/management/replication/
就是主从复制,master 以写为主,Slave 以读为主
当 master 数据变化的时候,自动将新的数据异步同步到其它 slave 数据库
如下图 : 主机有什么 , 从机有什么
作用:
读写分离
容灾恢复
数据备份
水平扩容支撑高并发
2. 使用
配从(库)不配主(库)
master 如果配置了 requirepass 参数 , 需要密码登陆
那么 slave 就要配置 masterauth 来设置校验密码 , 否则的话 master 会拒绝 slave 的访问请求
2.1 基本操作
info replication
可以查看复制节点的主从关系和配置信息
replicaof 主库IP 主库端口
一般写入进redis.conf
配置文件内slaveof 主库IP 主库端口
每次与 master 断开之后,都需要重新连接,除非你配置进redis.conf
文件在运行期间修改 slave 节点的信息,如果该数据库已经是某个主数据库的从数据库 , 那么会停止和原主数据库的同步关系转而和新的主数据库同步,重新拜码头
重新成为一个 Master 的从节点
slaveof no one
使当前数据库停止与其他数据库的同步,转成主数据库,自立为王
3. 配置
Master配置
daemonize 设置成 yes 是将 redis 以守护线程的方式启动,redis 会自动后台运行,但这个设置的前提是用在宿主机直接启动 redis。但使用 docker 启动 redis 时,使用默认的即可(即设置为no),否则启动的 docker 容器就无事可干了,docke r这时会自动退出,就会启动报错了
# 1. 开启damemonize yes (docker 模式启动不开)
dameonize yes
# 2. 注释掉bind 127.0.0.1或者改为0.0.0.0
# bind ...
bind 0.0.0.0
# 3.protected-mode 保护模式关闭
protected-mode no
# 4.指定端口
port 6379
# 5.指定工作目录
dir ./
# 6.pid文件名字
pidfile /var/run/redis.pid
# 7.日志文件名字
logfile "./logs/redis.log"
# 8.requirepass 密码
requirepass xxxxxxxx
# 9.dump.rdb名字
dbfilename dump6380.rdb
# 10.aof文件
appendonly yes
appendfilename "appendonly.aof"
Salve 配置 ( 包括上面哪些 )
# 1.从机访问主机的通行密码,mastterauth,必须 (从机配置)
masterauth xxxxx
# 2.主机的地址+端口
replicaof ... 6380
4. 一主二从
首先编写 docker-compose.yaml 文件
下载 redis.conf 文件: redis/redis.conf at unstable · redis/redis (github.com)
version: "3"
services:
redis_master:
image: redis:latest
volumes:
# 配置文件
- ./master/conf/redis.conf:/etc/redis/redis.conf
# 数据文件
- ./master/data:/data
network_mode: "bridge"
ports:
- "6380:6380"
container_name: MyRedis-master
command: redis-server /etc/redis/redis.conf
redis_slave1:
image: redis:latest
volumes:
# 配置文件
- ./slave1/conf/redis.conf:/etc/redis/redis.conf
# 数据文件
- ./slave1/data:/data
network_mode: "bridge"
ports:
- "6381:6381"
container_name: MyRedis-Slave1
command: redis-server /etc/redis/redis.conf
redis_slave2:
image: redis:latest
volumes:
# 配置文件
- ./slave2/conf/redis.conf:/etc/redis/redis.conf
# 数据文件
- ./slave2/data:/data
network_mode: "bridge"
ports:
- "6382:6382"
container_name: MyRedis-Slave2
command: redis-server /etc/redis/redis.conf
Master 日志显示从机同步成功
从机 日志
# 分别指定自己的端口启动redis服务
# master
redis-cli -p 6080
# slave1
redis-cli -p 6381
# slave2
redis-cli -p 6382
# 在master主机执行set,可以再salve上读到
master: set name 1234
salve1: key*
# 使用命令 info replication 信息
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.17.0.4,port=6381,state=online,offset=1425,lag=0
slave1:ip=172.17.0.3,port=6382,state=online,offset=1425,lag=0
master_failover_state:no-failover
master_replid:930f651fc5abda49c0eadb2154268743304e81a2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1425
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1425
4.2 主从复制细节
从机不可以执行写命令,从机只能读数据
从机中途断开连接,master 持续写入,从机恢复连接之后数据是可以和master保持一致的
因为首次连接会向 master 复制所有 key,后续是 master 写一条,存一条
主机 shutdown 之后,从机还是原地待命
从机数据可以正常读取,等待主机重启回来
主机重启后,主从关系不变
4.3 命令行指定
# 1.删除slave配置项目中的replicaof ....
另外两个redis变为了master
# 2.在命令行指定要跟随的master
slaveof .... 6381
# 3.使用 info replication
可以发现连个redis又回到了slave
命令行指定的方式,重启之后主从关系就不在了
5. 薪火相传
相当于 slave1 对上是 master 的从节点,对下是 slave2 的主节点
可以减轻主 master 的写压力
# 在salve2的redis-cli里执行slaveof
slaveof 172.17.0.5 6381
但是注意中间的 6381 依然不能写操,只是数据传递的方式发送了变化
6. 反客为主
# 使得一个从机从slave转变为master
slaveof no one
7. 主从复制工作流程
salve 启动成功连接到 master 后会发送一个 sync 命令
slave 首次连接 master , 会执行全量复制,slave 自身原有数据会被 master 数据覆盖清除
master 收到 sync 命令后会开始在后台保存快照( RDB 持久化),同时收集接收到的所有用户修改数据集命令缓存起来,master 节点执行完 RDB 持久化之后,master 将 rdb 快照文件和缓存命令发送给所有 slave,以完成一次完全同步
slave 收到数据后,加载到内存,完成复制初始化
master 每 10 秒发送心跳检测包,保持通信 repl-ping-replica-period 10
master 继续将新的所有收集到的修改命令自动依次传给 slave , 完成同步
slave 下线之后,master 会检查 backlog 中的 offset 偏移量,master 和 slave 都会保存一个复制的 offset 还有一个masterID,Master 只会包以及复制的 offset 后面的数据复制给 slave , 类似断点续传
5. 缺点和改进
复制延时,信号衰减
配置多台从机之后,Master 到 Salve 的同步延迟会越来越大
master 挂了怎么办
默认情况下不会再 slave 节点里面自动重选一个 master,所以需要人工干预
评论区