专栏首页upuptop的专栏2021年了,Redis复制原理你应该理解!

2021年了,Redis复制原理你应该理解!

Redis的单机模式不难,配置文件参数了解具体含义,设定业务上符合自己的就好了。

之前记录了关于Redis的数据结构和对象的知识(可以点Redis标签看看),下面开始填坑。


复制

在Redis中,用户可以通过执行 SLAVEOF 命令或者设置 slaveof 选项,让一个服务去复制(replicate)另一个服务器。被复制的服务器为主服务器(master),另一个对主服务器进行复制的服务器则被称为从服务器(slave)

举个?:(Redis版本是4.0.8)

在6379端口启动一个redis-server:
$ redis-server --port 6379
$ redis-cli -p 6379
127.0.0.1:6379> 



在6380端口号启动一个redis-server,接着通过slaveof命令进行复制
$ redis-server --port 6380
$ redis-cli -p 6380
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK

在这里,6379 是主服务器,6380 是从服务器。

接着能在 6380 的 redis-server 界面中看到日志:

19092:S 23 Mar 01:00:26.944 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
19092:S 23 Mar 01:00:26.945 * SLAVE OF 127.0.0.1:6379 enabled (user request from 'id=2 addr=127.0.0.1:60778 fd=8 name= age=50 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
19092:S 23 Mar 01:00:27.234 * Connecting to MASTER 127.0.0.1:6379
19092:S 23 Mar 01:00:27.234 * MASTER <-> SLAVE sync started
19092:S 23 Mar 01:00:27.234 * Non blocking connect for SYNC fired the event.
19092:S 23 Mar 01:00:27.246 * Master replied to PING, replication can continue...
19092:S 23 Mar 01:00:27.246 * Trying a partial resynchronization (request 2e56cf1343f6b2e864c968bd59b4a16ed78b8f1d:1).
19092:S 23 Mar 01:00:27.266 * Full resync from master: bf36b20c3942e91ac4f262a2afdc90970b2d7c54:0
19092:S 23 Mar 01:00:27.266 * Discarding previously cached master state.
19092:S 23 Mar 01:00:27.441 * MASTER <-> SLAVE sync: receiving 187 bytes from master
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Flushing old data
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Loading DB in memory
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Finished with success

具体流程如下:

  • 从服务器发送SYNC 命令到主服务器
  • 主服务器通过 BGSAVE(子线程中运行)生成 RDB 文件,发送给从服务器
  • 主服务器在 BGSAVE 过程中的写操作,保存在缓冲区中,发送给从服务器

进行复制中的主从服务器双方的数据库将保存相同的数据,概念上将这种现象称为“数据库状态一致”,或者简称“一致”。


旧版复制功能的缺陷(旧版指的是2.8之前)

在Redis中,从服务器对主服务器的复制可以分成两种情况:

  • 初次复制:从服务器从前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同。
  • 断线后重新复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重连接重新连上了主服务器,继续复制主服务器。

对于初次复制来说来说,旧版复制完全没有问题,但是断线重连之后,如果当时从服务器已经复制了一些,重连之后,从服务器需要重新复制,造成一些浪费。

旧版使用的是SYNC命令进行复制,是一个非常浪费资源的操作。


新版复制的优势

使用 PSYNC 命令替代 SYNC 命令来执行复制时的同步操作。

具有完整重同步(full resynchronization)部分重同步(partial resynchronization)两种模式:

  • 完整重同步:与初次复制相同,都是先让主服务器发送 RDB 文件,以及向从服务器发送保存在缓冲区里面的命令来进行同步。
  • 部分重分步:当从服务器断线的时候,下次可以发起 PSYNC 命令,从中断处开始,执行部分重同步,只需要将从服务器缺少的写命令发送给从服务器执行就可以了,这时使用的资源比起执行 SYNC 命令所需的资源要少的多。

新版复制实现

部分重同步功能由以下三个部分构成:

  • 主服务器的复制偏移量(replication offset)和从服务器的复制偏移量 主从服务器都各自持有一份复制偏移量。如果偏移量一致,表示处于一致状态;否则,两者处于不一致状态。
  • 主服务器的复制积压缓冲区((replication backlog) 复制积压缓冲区是由主服务器维护的一个固定长度(fixed-size)先进先出(FIFO)队列,默认是1MB。 主服务器的复制积压缓冲区里面会保存着一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量。 当从服务器重新连上主服务器时,从服务器会通过PSYNC命令将自己的offset发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作。
  • 服务器的运行ID(run ID) 每个服务器都有自己的运行 ID,在服务器启动时自动生成,由 40 个堆积的十六进制字符组成。 当从服务器对主服务器进行初次复制时,主服务器会将自己的运行ID传送给从服务器,而从服务器则会将这个运行ID保存起来。
    • 断线重连后,如果从服务器保存的运行 ID 与当前链接的主服务器的运行 ID 相同,主服务器会尝试执行部分重同步操作
    • 相反的,如果不一致,主服务器将对从服务器执行完整重同步操作

PSYNC命令实现

具体调用看流程图即可:


心跳检测

在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:

$ REPLCONF ACK <replication_offset>

其中replication_offset是从服务器当前的复制偏移量。发送REPLCONF ACK有三个作用:

  • 检测主从服务器的网络连接情况
  • 辅助实现min-slaves选项
  • 检测命令丢失

小结:

  • 部分重同步通过复制偏移量、复制积压缓冲区、服务器运行 ID三个部分来实现。
  • 在复制操作刚开始的时候,从服务器会成为主服务器的客户端,并通过向主服务器发送命令请求来执行复制步骤,而在复制操作的后期,主从服务器互相成为对方的客户端。
  • 主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从服务器一致,而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测。

本文分享自微信公众号 - 趣学程序(quxuecx),作者:点击关注 ????

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-01-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 2021年了,Redis复制原理你应该理解!

    之前记录了关于Redis的数据结构和对象的知识(可以点Redis标签看看),下面开始填坑。

    好好学java
  • 2021年了,Redis复制原理你应该理解!

    之前记录了关于Redis的数据结构和对象的知识(可以点Redis标签看看),下面开始填坑。

    程序员白楠楠
  • Redis面试题(2021最新版)

    作为一个后端开发人员,不只是要求开发人员需要掌握 Redis,也要求运维人员也要懂 Redis。由于 Redis 的运用广泛,我们也知道它的重要性,至此面试中经...

    Java程序猿
  • golang面试

    Michel_Rolle
  • Redis只能做缓存?太out了!

    redis丰富的数据结构,使得它的业务使用场景非常广泛,加上rdb的持久化特性,它甚至能够被当作落地的数据库使用。在这种情况下,redis能够撑起大多数互联网公...

    macrozheng
  • 【原创】Redis只能做缓存?太out了!

    大多数数据库,由于经常和磁盘打交道,在高并发场景下,响应会非常的慢。为了解决这种速度差异,大多数系统都习惯性的加入一个缓存层,来加速数据的读取。redis由于它...

    xjjdog
  • 赠书 | Redis数据库学习必备书籍!

    DB-Engines最近发布了2021年4月份的数据库排名。该网站根据数据库管理系统的受欢迎程度对其进行排名,实时统计了370种数据库的排名指数。前20名的排行...

    小F
  • 设计模式面试题(2021最新版)

    设计模式在日常的工作中,是非常重要的一项技能,使用设计模式可以重构整体架构代码、提交代码复用性、扩展性、减少代码冗余问题。这是每个 Java 工程师必备的技能!...

    Java程序猿
  • JVM虚拟机面试题(2021最新版)

    作为 Java 的从业者,在找工作的时候,一定会被问及关于 JVM 相关的知识。JVM 知识的掌握程度,在很多面试官眼里是候选人技术深度的一个重要评判标准。在这...

    Java程序猿
  • 国内首个云原生百科知识直播,精彩尽在每周二晚7点半!

    ? 云原生在近几年的发展越来越火热,作为云上最佳实践而生的设计理念,也有了越来越多的实践案例,而一个个云原生案例的背后,是无声的巨大变革。 腾讯云主办首个云原...

    腾讯云原生
  • 一文带你揭开Redis复制原理的神秘面纱

    墨墨导读:本文在依托Redis主从环境下,针对访问的数据一致性进行分析,解开Redis复制原理的神秘面纱。‍

    数据和云
  • Java虚拟机面试题(2021最新版)

    我坚信,机会永远属于有准备的人,我们与其羡慕他人的成功,不如从此刻起,积累足够多的知识和面试经验,为将来进入更好的公司做好充分的准备!想让面试官在短短的几十分钟...

    Java程序猿
  • 国内首个云原生百科知识节目,明晚7点半开播啦!

    ? 云原生在近几年的发展越来越火热,作为云上最佳实践而生的设计理念,也有了越来越多的实践案例,而一个个云原生案例的背后,是无声的巨大变革。 腾讯云主办首个云原...

    腾讯云原生
  • REDIS 哨兵 DOWN DOWN 灾难恢复方法记录

    为什么最近文章都开始在写灾难恢复,主要是DB TEAM 的每个DB 要掌握主机DOWN机后的恢复, 目前单位的虚拟机不是太稳定, 这边会遇到各种状况的DOWN ...

    AustinDatabases
  • Linux面试题(2021最新版)

    作为 Java 的从业者,在找工作的时候,一定会被问及关于Linux 相关的知识。Linux知识的掌握程度,在很多面试官眼里是候选人技术深度的一个重要评判标准。...

    Java程序猿
  • 这可能是你见过最好的Redis主从复制原理

    在Redis复制的基础上(不包括Redis Cluster或Redis Sentinel作为附加层提供的高可用功能),使用和配置主从复制非常简单,能使得从 Re...

    JavaEdge
  • 我的2020总结

    对于大多数人来说,2020年啥也没干,就光见证历史了。前一段时间华盛顿邮报向读者征集如何描述2020年,一个九岁小孩拔得头筹。 过马路前你左右都看了,结果被潜水...

    xindoo
  • 面试官嘲笑我,这你都不会?

    多年前刚毕业出来工作的时候,那个时候刚毕业对缓存的使用基本上可以说很少涉及,在大学做课件设计或者小型项目也都是用不到缓存,再者说了我大学是做嵌入式写汇编语言和c...

    我是阿沐
  • 2020技术总结

    口口声声的减肥大业终于还是荒废了,工作近六年,庆幸的是发量还可以(PS:可能是技术能力不达标)。

    merlinfeng

扫码关注云+社区

领取腾讯云代金券