RDB和AOF

RDB持久化

什么是RDB

  1. RDB持久化是记录当前时间节点内的Redis**快照信息**,可以根据快照信息可以用于Redis的**恢复**,主从模式的**第一次同步**
  2. 主进程会**fork**出一个子进程,子进程进行RDB文件的生成,当主进程正在进行读操作时,则会与子进程一起读取公共内存中的内容。当主进程正在进行写操作时,则会将内容拷贝一份进行操作,不影响子进程的RDB操作。
  3. 子进程完成新的RDB文件写入完成后,删除原有的RDB文件

RDB的触发条件

  1. **save** 利用**主进程**进行RDB的备份,会阻塞所有请求
  2. **bgsave** fork出**子进程**进行RDB操作,此时仍可以处理其他请求
  3. 当Redis关闭时,会自动触发一次RDB操作,用于重启时的数据恢复
  4. 当Redis的请求次数达到设定的若干条件 设置的规则为 xxx秒内有多少条数据修改的请求

AOF持久化

什么是AOF

  1. 在Redis**执行命令后**,都会将操作记录到**AOF缓冲区**中,然后再**write**写到 **Page Cache**
  2. 只有调用了**fsync** 进行持久化到磁盘后,文件才真正持久化完成,如果在fsync执行之前,机器宕机,则这部分的AOF日志会丢失

AOF的基本流程

  1. 当Redis执行完一条写操作指令后,会将该命令追加(append)到**AOF缓冲区**
  2. 在加入到缓冲区后会同时调用写入(**write**)命令,将AOF缓冲区的数据写入到中**内核缓冲区**(Page Cache)
  3. 参数包含**三种**选项,**每次write**都进行fsync刷盘,**后台线程每秒钟**执行一次fsync刷盘,和不主动刷盘,有操作系统自行决定何时刷盘(大约30秒)
  4. 每次write操作之后都进行刷盘则过于浪费系统资源,一般设定为后台线程**每秒钟执行一次fsync刷盘**操作
  5. 当AOF文件过大时会进行**文件重写**,重写是耗费资源的过程,因此会创建子进程进行AOF的重写操作,这里的重写操作只记录每个key最后一次的操作,因此可以在保证与原AOF文件语义相同的情况下减少大量的空间,在原AOF文件重写完毕后,再把新的缓存文件加入到重写后的AOF文件中
  6. 当系统重启时,通过**load**进行AOF文件来恢复数据
  7. 如果每次执行完一句写语句就写入磁盘,则是随机IO并且一次只操作一条数据。
  8. 现在通过**WAL机制**,将**随机IO**改为**顺序IO**,并且把**单条语句的操作**改为**批量操作**,提高性能。

image.png

RDB和AOF的区别

RDB的优势

  1. **RDB**是对整个Redis的快照保存的是**二进制数据****文件体积较小**,而**AOF**的文件记录的是**每一条指令****文件体积较大**
  2. RDB记录的是实际的数据集,而AOF记录的是实际的操作,因此在恢复的过程中,**RDB的恢复速度比AOF要快很多**

AOF的优势

  1. RDB需要开启子进程同时对整个Redis进行文件的写入保存,虽然这个操作可以由子进程在后台异步执行,但是仍然是一个非常耗费资源的操作,而AOF可以以较低的消耗保证秒级的信息丢失
  2. 不同版本的Redis中有对应不同的RDB格式文件,不同的Redis版本中可能会不兼容
  3. AOF的日志可以进行解析

主从模式信息同步

主从同步会从读库中读到旧数据吗

  1. 根据不同的版本和命令情况,可能会从读库中读到旧数据
  2. 在Redis 3.2之前,在从库中读取数据时不会判断该key是否过期,因此可能从读库中查询到过期的key
  3. 在Redis3.2之后,在从库中读取数据时会先判断该key是否已经过期,如果过期则会将该key设置为null,并且返回null
  4. 如果是主库中的命令执行的是 通过**expire**添加过期时间,则添加的是**ttl**值,即是当前时间节点添加ttl后为最终的过期时间。从主库将命令同步过来时会导致,主库中的key已经过期了,但从库中的key还没有过期。
  5. 使用 **expireAt**命令可以解决这个问题,同样是设置过期时间,但是expireAt设定的是指定的时间戳,因此主库和从库的信息会同时过期,因此不会在从库中读取到过期的信息。

SYNC 同步

  1. master节点会为每个slave节点开辟一块空间,replication buffer(复制缓冲区)用于存储每个slave节点在生成RDB文件后的写命令,占用空间
  2. slave在加载RDB文件时,无法对外提供读操作
  3. 在每次slave与Master节点断开连接后,无论什么原因都需要进行全量同步,全量同步的bgsave操作是非常耗费时间的。

image.png

PSYNC 同步

  1. 相比于SYNC同步,因网络问题短暂与Master节点断开连接后,可以通过runId查询到是否相等,如果Master中有缓存对应的数据,则只需要进行增量同步
  2. 但是当slave突然被宕机或重启时,或是Master节点宕机,重新选取Master节点后,这些情况都会导致runId和offset发生改变,因此需要重新进行全量同步。

image.png

PSYNC 2.0

PSYNC2.0的优化
  1. 相比于PSYNC进行优化,在出现了选举出新Master的情况,在PSYNC2.0中仍然有可能执行增量同步。在PSYNC2.0中使用 replid和replid2代替了原有的runId
  2. slave节点中的replid是当前正在同步的Master节点的replid,replid2是上一个Master节点的replid
  3. Master节点中的replid是就是自己的复制id,在初始时,replid2为空,当发生主从切换后,新的Master节点的replid2则会上一个正在同步的Master的replid
  4. 在Master节点宕机后,可以通过replid属性判断Slave和新Master之前是否所属同一个Master节点,如果是则可以进行增量同步
全量同步的具体过程
  1. Slave节点像master节点发出增量同步请求,会带上 replid和offset
  2. replid代表数据集,相同的数据集他们的replid是相同的
  3. Master判断 请求中的replid与自己的是否相同,如果不相同,或Offset不符合要求则说明是第一次进行全量同步,并将Master节点的replid和offset发送给slave节点
  4. slave收到后保存信息,此时slave节点的replid和offset和上一版本的Master节点相同
  5. Master确认要进行全量同步,此时会fork一个子进程开始进行 bgsave 备份RDB文件,同时会将在RDB进行时收到的所有命令保存到repl_baclog中
  6. Master将RDB文件发送给Slave,slave节点清空所有原始数据,利用RDB文件进行恢复
  7. Master将repl_baclog发送给Slave,Slave执行log中保存的命令

image.png

增量同步

什么时候回出现增量同步

除了Slave第一次对Master进行全量同步和与Master断开连接过久外,其余的同步都是增量同步

增量同步的具体过程
  1. Slave节点像Master节点发出增量同步的请求,发送Slave节点的replid和offset
  2. Master节点判断出请求的replid与Master节点相同,并且offset符合要求,于是给slave节点回复continue
  3. Master节点将Slave节点后的数据发送给Slave节点,Slave执行命令从而同步数据。

image.png

repl_backlog_buffer 中保存的信息

  1. repl_backlog_buffer 是一个数组,Master会循环的进行信息的写入
  2. Master在一直进行写入时,slave也在一直进行读取,与复制缓冲区会为每个slave分配一块内存不同的是,repl_backlog_buffer是所有slave共用一个的
  3. 当写完一圈后,会继续覆盖先前以后得数据继续写入
  4. 但是当slave节点由于网络问题或其他问题,导致一段时间没有进行增量同步,master节点覆盖了slave节点,此时则需要进行全量同步

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值