【redis】主从复制:拓扑结构、原理和psync命令解析

文章目录

拓扑

若干个节点之间按照什么样的方式来进行组织连接

一主一从

  • 都可以读,从节点可以帮主节点分担一部分的压力
  • 只有主节点能写
    解决了单点并发量不高和单点可能出现故障的情况

相关问题

  1. 写请求太多
    但是如果写请求太多,也会给主节点造成一些压力。
  • 此时我们可以通过关闭主节点的 AOF,只在从节点上开启 AOF 的方式降低主节点的压力
  • AOF 需要将数据写到硬盘上,而写硬盘比写内存要慢上不少,因此让主节点就只写内存,这样主节点能支持的并发量就更大了
  1. 数据丢失
    但是这种设定方式,有一个严重的缺陷:主节点一旦挂了,不能让他自动重启(如果自动创奇,此时没有 AOF 文件,就会丢失数据,进一步的主从结构,会把从节点的数据也给删了)

改进办法 :当主节点挂了之后,就需要让主节点从从节点这里获取到 AOF 文件,然后再启动

一主多从

在实际开发中,读请求的数量是远远超过写请求的,此时我们就可以用一主多从的结构

  • 主节点上的数据发生改变,就会把改变的数据同时同步给所有的从节点

相关问题

  1. 网络带宽压力
    随着从节点个数的增加,同步一条数据,就需要传输多次,主节点的网络带宽要压力是很大的

解决办法:使用树形主从结构

树形主从结构

可以有效的缓解主节点网络带宽压力大的情况

  • 这样就把同步数据的网络压力,均摊到多个节点上了,主节点就不需要那么高的网络带宽了

相关问题

  1. 同步时间变长
    一旦数据进行修改了,同步数据的延时是比一主多从结构要长的,

主从复制原理

复制流程

  1. 先保存主节点的 IP 和端口(在一个变量中)
  2. 然后建立一个 TCP 连接(三次握手)
  3. 通过 ping 命令,验证主节点是否能够正常工作(站在应用程序角度)
    • 上面的 TCP 三次握手,验证的是通信双方能否正常读写数据,而不是能否正常工作(站在系统层面)
    • 检查路修好了没(三次握手);检查这辆车子是不是好的(ping
  4. redis 主节点如果开启了密码,就会触发"权限认证"

上面的都是准备操作,最关键的复制操作就是第五步和第六步

  • 同步数据集 :相当于全量同步。在进行同步的一瞬间,一次性把所有的数据都给我
  • 命令持续复制 :相当于增量同步。后续再有数据变化,继续进行同步

psync 命令

redis 提供了一个 psync 命令,完成数据同步的过程

  • 不需要我们手动执行,redis 服务器会在建立好主从同步关系之后,自动执行 psync
  • 从节点负责执行 pysnc,从节点从主节点这边拉取数据(从节点主动要,而不是主节点主动给)

语法格式为:

redis 复制代码
PSYNC replicationid offset

命令解析

replicatonid

  • replicationid:理解成复制 Id,是主节点在启动的时候生成的(从节点变成主节点的时候也会生成 ,下面有谈到)
    • 即使是同一个主节点,每次重启,生成的 replication id 都是不同的
    • 从节点和主节点建立了复制关系,就会从主节点这边获取到 replication id
    • 此处讨论的都是一个主节点,多个从节点。

我们可以通过 info 命令,获取到 replication id

redis 复制代码
info replication
  • 一般情况下,replid2 是用不到的

使用到 replid2 的情况

  • 有一个主节点 A,还有一个从节点 B。 A 生成 replid,B 获取到 A 的 replid
  • 如果 A 和 B 通信过程中出现了一些网络抖动,B 可能就会认为 A 挂了,于是 B 就会自己成为主节点,给自己生成一个 replid
  • 此时 B 也会记得旧的 replid,就是通过 replid2
  • 后续网络稳定了,B 还可以根据 replid2 重新回到 A 的怀抱
    • 需要手动干预。不过哨兵机制可以自动完成这个过程

offset

可以理解成偏移量,主节点和从节点上都会维护偏移量(整数)

  • 主节点上:主节点会收到很多的修改操作的命令,每个命令都要占据几个字节,主节点会把这些修改命令的字节数进行累加,就会得到一个逐渐变大的数字
  • 从节点上:描述了现在从节点这里的数据同步到哪里了
  • 如果从节点和主节点这里的偏移量一样,就说明同步完成了
  • 从节点(slave)每秒钟上报自身的复制偏移量给主节点

总结

replicationidoffset 共同描述了一个"数据集合"

如果发现两个机器,replicationid 一样,offset 也一样,就可以认为这两个 redis 机器上存储的数据就是完全一样的

  • 主服务器看做银行总行,从服务器看做分行
    • 总行里面有很多客户,每个客户都有一个自己的账户,用 replicationid 表示账户,offset 表示订单数量
    • 比如张三的账户 replicationid123123,他此时转出 100 元,总行实时记录,订单数量 offset 为 1,随后同步给分行
  • 只要总行和分行里面,账户号 replicationid 和订单数量 offset 一样,就说明两边的数据是一样的,如果分行的订单数量 offset 比总行的少,那就说明还没同步完成

运行流程

  • FULLRESYNC:全量数据的同步

  • CONTINEU:增量数据的同步

  • ERR:比较老版本的 redis 服务器不支持 psync(可以用 sync,会阻塞 redis 服务器)

  • psync 这里可以从主节点获取全量数据,也可以获取一部分数据,主要就是看 offset 这里的进度

    • offset 写作 -1,就是获取全量数据
      • 获取所有数据是最稳妥的,但是会比较低效
    • offset 写具体的正整数,则是从当前偏移量位置来进行获取
      • 如果从节点之前已经从主节点这里复制过一部分数据了,就只需要把新的之前没复制过的数据搞过来即可

不是从节点索要哪部分,主节点就一定给哪部分。主节点会自行判断,看当前是否方便给哪部分数据,不方便就只能给全量数据了


什么时候进行全量复制?

  1. 首次和主节点进行数据同步
  2. 主节点不方便进行部分复制的时候

什么时候进行增量复制?

  • 从节点之前已经从主节点上复制过数据了。因为网络抖动或者从节点重启了,从节点需要重新从主节点这边同步数据,此时看看能不能只同步一笑部分(大部分数据都是一致的)
    **
相关推荐
Full Stack Developme33 分钟前
SQL 版本历史
数据库·sql
大刀爱敲代码34 分钟前
基础算法01——二分查找(Binary Search)
java·算法
追风少年1553 小时前
常见中间件漏洞之一 ----【Tomcat】
java·中间件·tomcat
杰克逊的日记3 小时前
mysql数据实时全量+增量迁移
数据库·mysql·数据迁移
yang_love10113 小时前
Spring Boot 中的 @ConditionalOnBean 注解详解
java·spring boot·后端
郑州吴彦祖7724 小时前
【Java】UDP网络编程:无连接通信到Socket实战
java·网络·udp
linuxxx1104 小时前
centos7 升级MariaDB 到 10.5 或更高版本
数据库·mariadb
换个网名有点难4 小时前
django怎么配置404和500
数据库·django
spencer_tseng4 小时前
eclipse [jvm memory monitor] SHOW_MEMORY_MONITOR=true
java·jvm·eclipse
鱼樱前端4 小时前
mysql事务、行锁、jdbc事务、数据库连接池
java·后端