# Redis 主从架构
单节点 Redis 的并发能力是有上限的,要进一步提高 Redis 的并发能力,就需要搭建主从集群,实现读写分离

# 开启主从关系
三个实例还没有任何练习,要配置主从可以使用 replicaof 或者 slaveof (5.0 以前) 命令
有临时和永久两种模式 :
修改配置文件 (永久生效)
- 再 redis.conf 中添加一行设置 :
slaveof <masterip> <masterport>
- 再 redis.conf 中添加一行设置 :
使用 redis-cli 客户端连接到 redis 服务,执行 slaveof (重启后失效) :
1
slaveof <masterip> <masterport>
注意:在 5.0 以后新增命令 replicaof, 与 slaveof 效果一致
单一主机通过 Docker 设置 Redis 主从模式坑点 : Docker 创建的容器如果没有指定说明,默认都是挂载在 Docker 内部的网卡中,在这个网卡中,所有的容器都可以相互通信,他们也都有对应的 IP 地址。我一开始使用 replicaof 127.0.0.1 6380 这个命令,但是连接不上。我想的是在宿主机的角度,所有的 Redis 容器都绑定在宿主机的不同的端口中,那么我只需要访问本机 IP 的其他端口就行了。但实际上,我是在 Docker 容器中运行的,以上命令相当于在该容器中找其他端口中的 Redis, 所以肯定找不到.
正确的操作方式是:在宿主机中使用 docker inspect <容器ID或name> , 查看不同容器的 IP 地址,然后再使用这个 IP 地址进行通信.
# 数据同步原理
# 全量同步
主从第一次同步是全量同步 :

master 如何判断 slave 是不是第一次来同步数据?
- Replication Id: 简称 replid, 是数据集的标记,id 一致则说明是同一数据集。每一个 master 都有唯一的 replid, slave 则会继承 master 节点的 replid
- offset: 偏移量,随着记录再 repl_baklog 中的数据增多而逐渐增大. slave 完成同步也会记录当前同步的 offset. 如果 slave 的 offset 小于 master 的 offset, 说明 slave 数据落后于 master, 需要更新
因此 slave 做数据同步,必须向 master 声明自己的 replication id 和 offset, master 才可以判断到底需要同步哪些数据
简述全量同步的流程
- slave 节点请求增量同步
- master 节点判断 replid, 返现不一致,拒绝增量同步
- master 将完整内存数据生成 RDB, 发送 RDB 到 slave
- slave 清空本地数据,加载 master 的 RDB
- master 将 TDB 期间的命令记录在 repl_baklog, 并持续将 log 中的命令发送给 slave
- slave 执行接收到的名利,保持与 master 之间的同步
# 增量同步
主从第一次同步全量同步,但如果 slave 重启后同步,则执行增量同步

注意: repl_baklog 大小有上限,写满后会覆盖最早的数据。如果 slave 断开时间过久,导致尚未备份的数据被覆盖,则无法基于 log 做增量同步,只能再次全量同步
可以从以下几个方面来优化 Redis 主从集群 :
- 在 master 中配置 repl-diskless-sync yes 启用无磁盘复制,避免全量同步时的磁盘 IO
- Redis 单节点上的内存占用不要太大,减少 RDB 导致的过多磁盘 IO
- 适当提高 repl_baklog 的大小,发现 slave 宕机时尽快实现故障恢复,尽可能避免全量同步
- 限制一个 master 上的 slave 节点数量,如果实在太多 slave, 则可以采用主 - 从 - 从链式结构,减少 master 压力

# 总结
简述全量同步和增量同步区别?
- 全量同步: master 将完整内存数据生成 RDB, 发送 RDB 到 slave. 后续命令则记录在 repl_baklog, 诸葛发送给 slave
- 增量同步: slave 提交自己的 offset 到 master, master 获取 repl_baklog 中从 offset 之后的命令给 slave
什么时候执行全量同步?
- slave 节点第一次连接 master 节点时
- slave 节点断开时间太久,repl_baklog 中的 offset 已经被覆盖时
什么时候执行增量同步?
- slave 节点断开后又恢复,并且在 repl_baklog 中能找到 offset 时
