增加了部分重同步,这个要怎么做才能兼容之前的全量同步呢?怎么知道从库复制到哪儿了?第一个从库肯定要记录下从库复制到哪儿了,下次断线重连时就可以告诉主库该从哪个地方开始复制了 。主库也要记录自己的一些复制信息 。Redis 用了几个概念就把这些问题给解决了 , Replication ID,offset,replication_backlog 。
- Replication ID:复制 ID 。这是一个较大的随机字符串,标记一个给定的数据集 。每个主节点都会用这个 Repli ID 来标识内部数据集,从节点 ID 。当从节点加入时 , 这个 repli id 就初始化了 。
- offset:复制偏移量 。每个主节点都有这个 offset 偏移量 , 主节点将自己产生的数据发送给从节点时,发送多少字节数据,自身 offset 就会增加多少 。从节点也有自己 offset,从节点写入数据时,offset 也会增加 。断线重连时,就可以知道从哪里开始同步了 。offset 需配合下面的复制积压缓冲区工作 。
- replication_backlog:复制积压缓冲区 。它是在主节点上的一个环形缓冲区,用来存储主节点向从节点传递的命令 。它是大小固定 , 存储的命令有限,所有超出了就会删除 。从节点进行增量同步时,主节点会根据 offset 从 replication_backlog 中拷贝从节点缺失的数据到从节点 。
Redis2.8之后就是用上面这几个概念实现部分数据重同步的 。从节点发送主节点的 replid 和从节点的一个 offset,主节点拿到这个replid 和自己的 replid 比较,如果是一样,并且这个 offset 也在 backlog 中能找到,那就可以可以进行部分重同步 。
全量复制步骤
- 主从节点先建立连接
主节点收到 PSYNC 命令后,会用 FULLRESYNC 命令响应,带上主节点的 replid 和 offset 返回给从库,从库会记录下这两个参数 。便于以后判断是否需要部分重同步 。
- 同步数据
- 同步缓冲的命令数据
当主库把 RDB 文件传送给从节点完成后,就会把 replication buffer 中的写命令操作发送给从节点,从节点执行这些操作命令,主从节点同步完成 。
- 命令传播
上面是一个主体的同步步骤,更加详细的步骤要分析源码了 。
发送步骤与 Redis2.8 之前全量同步没有多大区别 。
部分数据同步部分数据同步,解决的是主从节点在同步命令时候,网络断了在连上时,Redis2.8 之前会在全量同步数据 , 显然开销太大,不合理 。能不能只把断线后的数据同步一份,而不是全量同步?
网络断线后,就有部分命令数据没有同步到从节点上去,那我们能不能保存这部分命令数据?重连后 , 将断开期间的这部分命令重新同步给从节点,这样就不需要全量同步 。
Redis2.8 之后引入了 replication_backlog 复制积压缓冲区,前面有讲到这个概念 。命令一方面会传输给从节点,另外还会记录在这个复制积压缓冲区里 。Redis 使用一个环形缓冲区的结构保存最近的一些命令 。在缓冲区中,对字节进行编号 , 这个编号在 Redis 中叫复制偏移量 。
文章插图
是否部分同步条件?
- 从节点 replid 和 主节点的 replid 相同
- 复制偏移量 offset 在复制积压缓冲区的 backlog_off 和 offset 范围之间 。
推荐阅读
- flinksql读写redis
- 追求性能极致:Redis6.0的多线程模型
- spring boot集成redis基础入门
- CentOS 7.9 安装 redis-6.2.0
- Redis实现布隆过滤器解析
- 18-基于CentOS7搭建RabbitMQ3.10.7集群镜像队列+HaProxy+Keepalived高可用架构
- 深入底层C源码 Redis核心设计原理
- Redis高并发分布式锁详解
- 原生Redis跨数据中心双向同步优化实践
- 马最高可以活几年?