Redis主从数据同步过程:命令传播、部分重同步、复制偏移量等

请记住胡广一句话,所有的中间件所有的框架都是建立在基础之上,数据结构,计算机网络,计算机原理大伙一定得看透!!~

1. Redis数据同步

1.1 数据同步过程

大家有没想过为什么Redis多机要进行数据同步?不会是MySQL主从架构要数据同步,Redis就照猫画虎吧。

虽然这两者有关系型数据库和非关系型数据库的差异,但都是作为存储数据的数据库系统。而主从架构的目的就在于对数据有多个"备份",有了多个"备份",就自然而然衍生出众多好处。如负载均衡、灾难恢复、数据备份。

既然要"备份",那数据同步就必不可少了。Redis主从数据同步大致的过程如下。

  1. 首先,从服务器会先向主服务器发送SYNC命令
  2. 收到命令后,Redis主服务器会执行BGSAVE命令 来生成一个RDB文件 ,并使用AOF缓冲区来记录在生成期间执行的写命令。关于BGSAVE命令和SAVE命令的区别,大家可以往前阅读我写的Redis系列文章。
  3. 完成第二步后,主服务器会将RDB文件发送给从服务器,让从服务器同步RDB文件数据。
  4. 当然这还没完,在生成RDB文件的过程中,仍然会有其他写命令到达服务器。Redis主服务器的AOF缓冲区会继续发送给从服务器,让它们之间的数据同步至最终状态

1.2 命令传播

有了AOF缓冲区的概念还没完,Redis主从复制还有一个命令传播的概念等着你去学。

从服务器使用SYNC进行初次数据同步后,主、从服务器的数据库状态并不是每时每刻都保持一致的,这种情况反而是常态。肯定不能为了一条写指令的差异就重新执行SYNC命令,因为SYNC命令是一个非常耗费资源的操作。

这种情况Redis主服务器会将造成主从服务器数据不一致的写命令,即最近执行的写命令,发送给从服务器执行。这便是命令传播的过程,当从服务器执行命令后,主从服务器的数据库状态也就保持了一致。

如果后续有新的命令写入主服务器,主服务器会继续重复命令传播的过程。

1.3 部分重同步

主从服务器断线的话,假设你是Redis开发者,要怎么高效地恢复主、从服务器数据同步的状态。

如果还是用的RDB文件来同步,也太浪费资源了。有可能只是短时间断线,执行的写命令不过几十个,上文我已经提到SYNC命令是很耗费资源的一种操作。

能不能有一支记号笔,在主、从服务器断线时在主服务器的命令队列画下一个记号?

其实Redis除了提供SYNC命令的支持,还有一个叫PSYNC命令

主从服务器断线后,Redis从服务器会发送一个PSYNC命令给主服务器。收到命令后主服务器会将两者断线期间执行的写命令一条不剩地发送给从服务器。

从服务器执行命令后,主、从服务器的数据也就同步了。这种同步方式也叫部分重同步

1.4 复制偏移量

提前剧透下,前面提到的记号笔就是复制偏移量 ,命令队列也就是复制积压缓冲区队列

Redis主、从服务器都会去维护一个复制偏移量 ,复制偏移量是什么?例如主从服务器的初始偏移量都是0,主服务器发送给从服务器N字节数据 后,主从服务器的偏移量就会 + N。复制偏移量通过该数值来代表主服务器发送给从服务器的字节总量

通过复制偏移量就可以来记录同步状态。

Redis其实有是一个容器来存储命令传播 的写命令,命令传播的命令保存在一个有复制偏移量 标识的复制积压缓冲区队列。

从服务器发送PSYNC命令给主服务器,还会同时发送从服务器的复制偏移量。主服务器只要根据该复制偏移量在复制积压缓冲区队列中找到对应的命令,就可以发送相关命令给到从服务器。

2. 服务器运行ID

每个Redis节点都有自己的服务器运行ID,这个ID由服务器启动时自动生成。

当从服务器对主服务器进行初次复制 时,主服务器会将自己的运行ID传送给从服务器,而从服务器则会将这个运行ID保存起来。

当断线后数据同步时,从服务器会向当前连接的主服务器发送之前保存的主服务器运行ID

如果此时主服务器发现从服务器发送的运行ID 与自己的不一致。那就说明此时的主服务器是新的 主服务器,它也没有复制积压缓冲区 队列,也就不能进行部分重同步。此时Redis主服务器会向从服务器发送RDB文件来进行数据同步。

3. Redis心跳检测

从服务器默认会每秒一次向主服务器发送心跳检测命令,如果主服务器超过1s没有收到replconf命令,说明主从服务器的网络连接有问题了。

以下是心跳检测命令。

复制代码
REPLCONF ACK <replication_offset>

同时这个心跳检测命令还会附带传送一个复制偏移量 ,也就是上文的replication_offset

在心跳检测时的过程中,如果主服务器发现他们的复制偏移量不一致,就会通过该偏移量找到从服务器丢失的写命令,从而发送给从服务器保持同步。

到这我们就知道了,心跳检测不仅仅能让主服务器检测从服务器是否存活。Redis开发者很聪明,在从服务器发送心跳检测命令时添加复制偏移量,让心跳检测也具有检测命令丢失的功能。

你好,我是胡广。 致力于为帮助兄弟们的学习方式、面试困难、入职经验少走弯路而写博客 🌹🌹🌹 坚持每天两篇高质量文章输出,加油!!!🤩

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注 吧 我会尽力带来有趣的内容 。

😎感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以 给我留言咨询,希望帮助更多的人
更多专栏:

📊 Java设计模式宝典:从入门到精通(持续更新)

📝 Java基础知识:GoGoGo(持续更新)

Java面试宝典:从入门到精通(持续更新)

🌟 程序员的那些事~(乐一乐)

🤩 Redis知识、及面试(持续更新)

🚀 Kafka知识文章专栏(持续更新)

🎨 Nginx知识讲解专栏(持续更新)

📡 未完待续。。。

🎯 未完待续。。。

🔍 未完待续。。。

感谢订阅专栏 三连文章

相关推荐
Dlwyz3 小时前
redis-击穿、穿透、雪崩
数据库·redis·缓存
工业甲酰苯胺5 小时前
Redis性能优化的18招
数据库·redis·性能优化
Oak Zhang8 小时前
sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
redis·mysql·缓存
门牙咬脆骨9 小时前
【Redis】redis缓存击穿,缓存雪崩,缓存穿透
数据库·redis·缓存
门牙咬脆骨9 小时前
【Redis】GEO数据结构
数据库·redis·缓存
墨鸦_Cormorant10 小时前
使用docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像
redis·nginx·docker
Dlwyz13 小时前
问题: redis-高并发场景下如何保证缓存数据与数据库的最终一致性
数据库·redis·缓存
Stara051114 小时前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi
飞升不如收破烂~14 小时前
redis的List底层数据结构 分别什么时候使用双向链表(Doubly Linked List)和压缩列表(ZipList)
redis
吴半杯15 小时前
Redis-monitor安装与配置
数据库·redis·缓存