今天想和你们分享有关 Redis 主从同步(也称「复制」)的内容。程序员
咱们知道,当有多台 Redis 服务器时,确定就有一台主服务器和多台从服务器。通常来讲,主服务器进行写操做,从服务器进行读操做。面试
那么这里有存在一个问题:从服务器如何和主服务器进行数据同步的呢?数据库
这个问题,就是经过今天的内容:主从同步来解决的。性能优化
文章内容依旧比较干,建议你们静下心来专心看,文末会给你们作个简单总结概括。服务器
假如,如今有 2 台 Redis 服务器,地址分别是 127.0.0.1:6379 和 127.0.0.1:12345网络
咱们在 127.0.0.1:12345 的客户端输入命令:架构
127.0.0.1:12345> SLAVEOF 127.0.0.6379并发
如此 127.0.0.1:12345 服务器就会去复制 127.0.0.1:6379 的数据。即前者是从服务器,后者为主服务器。分布式
除了以上方式进行复制以外,还能够经过配置文件中的 slaveof 选项进行设置。微服务
可能,求知欲爆棚的你会想知道,Redis 是怎么进行主从同步的?
ok,下面咱们继续了解一下。
主从同步分为 2 个步骤:同步和命令传播
上面就是主从同步 2 个步骤的做用,下面我打算稍微细说这两个步骤的实现过程。
这里须要提早说明一下:在 Redis 2.8 版本以前,进行主从复制时必定会顺序执行上述两个步骤,而从 2.8 开始则可能只须要执行命令传播便可。在下文也会解释为何会这样?
从服务器对主服务的同步操做,须要经过 sync 命令来实现,如下是 sync 命令的执行步骤:
从服务器向主服务器发送 sync 命令
收到 sync 命令后,主服务器执行 bgsave 命令,用来生成 rdb 文件,并在一个缓冲区中记录从如今开始执行的写命令。
bgsave 执行完成后,将生成的 rdb 文件发送给从服务器,用来给从服务器更新数据
主服务器再将缓冲区记录的写命令发送给从服务器,从服务器执行完这些写命令后,此时的数据库状态便和主服务器一致了。
用图表示就是这样的:
通过同步操做,此时主从的数据库状态其实已经一致了,但这种一致的状态的并非一成不变的。
在完成同步以后,也许主服务器立刻就接受到了新的写命令,执行完该命令后,主从的数据库状态又不一致。
为了再次让主从数据库状态一致,主服务器就须要向从服务器执行命令传播操做 ,即把刚才形成不一致的写命令,发送给从服务器去执行。从服务器执行完成以后,主从数据库状态就又恢复一致了。
这里插播一个疑问:
不知道有没有的读者以为,当发生上述不一致的状况后,Redis 再执行同步操做不就 ok 了吗?
从效果上来讲,的确是能够恢复同步,但其实没有必要。缘由是实现同步的 sync 命令是一个很是消耗资源的操做,看完下图的说明,相信你确定理解的。
在此我向你们推荐一个程序员交流群。交流学习群号:833145934 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源与最新的BAT面试题,目前受益良多
还记得上面说的内容吗 —— 2.8 版本开始,进行主从同步可能只须要执行命令传播便可。这个也是由于 sync 比较耗资源,从而采起的优化。
那何时能够这么作呢?咱们先看下前提条件:
主从同步实际分 2 种状况:
在断线后重复制的状况下,在 2.8 版本以前,会再次执行同步(sync 命令)和命令传播。
若是说,在断线期间,主服务器(已有上万键值对)只执行了几个写命令,为了让从服务器弥补这几个命令,却要从新执行 sync 来生成新的 rdb 文件,这也是很是低效的。
为了解决这个问题,2.8 开始就使用 psync 命令来代替 sync 命令去执行同步操做。
psync 具备完整重同步和部分重同步两种模式:
所以很明显,当主从同步出现断线后重复制的状况,psync 的部分重同步模式能够解决 sync 的低效状况。
上面的介绍中,出现了「知足必定条件」,那又是鬼什么条件呢?—— 其实就是一个偏移量的比较,具体能够继续往下看。
部分重同步功能由如下 3 部分组成:
执行复制的主从服务器都会分别维护各自的复制偏移量:
举个例子:
若当前主服务器的复制偏移量为 10000,此时向从服务器传播 30 个字节数据,结束后复制偏移量为 10030。
这时,从服务器还没接收这 30 个字节数据就断线了,而后从新链接上以后,该从服务器的复制偏移量依旧为 10000,说明主从数据不一致,此时会向主服务器发送 psync 命令。
那么主服务器应该对从服务器执行完整重同步仍是部分重同步呢?若是执行部分重同步的话,主服务器又如何知道同步哪些数据给从服务器呢?
如下答案都和复制积压缓冲区有关
首先,复制积压缓冲区是一个固定长度,先进先出的队列,默认 1MB。
当主服务器进行命令传播时,不只会将命令发送给从服务器,还会发送给这个缓冲区。
所以复制积压缓冲区的构造是这样的:
当从服务器向主服务器发送 psync 命令时,还须要将本身的复制偏移量带上,主服务器就能够经过这个复制偏移量和复制积压缓冲区的偏移量进行对比。
若复制积压缓冲区存在从服务器的复制偏移量 + 1 后的数据,则进行部分重同步,不然进行完整重同步。
运行 id 是在进行初次复制时,主服务器将会将本身的运行 id 发送给从服务器,让其保存起来。
当从服务器断线重连后,从服务器会将这个运行 id 发送给刚链接上的主服务器。
若当前服务器的运行 id 与之相同,说明从服务器断线前复制的服务器就是当前服务器,主服务器能够尝试执行部分同步;若不一样则说明从服务器断线前复制的服务器不是当前服务器,主服务器直接执行完整重同步。
花了不少笔墨,终于把部分重同步的实现写完了,最后补充一个辅助功能
刚才提到,主从同步有同步和命令传播 2 个步骤。
当完成了同步以后,主从服务器就会进入命令传播阶段,此时从服务器会以每秒 1 次的频率,向主服务器发送命令:REPLCONF ACK <replication_offset> 其中 replication_offset 是从服务器当前的复制偏移量
发送这个命令主要有三个做用:
发送 SLAVEOF 命令能够进行主从同步,好比:SLAVEOF 127.0.0.6379
主从同步有同步和命令传播 2 个步骤。
主从同步分初次复制和断线后重复制两种状况
2.8 版本使用 psync 命令来代替 sync 命令去执行同步操做。目的是为了解决同步(sync 命令)的低效操做。
以上就是这篇文章的所有内容了,但愿本文的内容对你们的学习或者工做具备必定的参考学习价值。