【redis:二】持久化

RDB

RDB持久化是把当前进程数据生成快照存到硬盘的过程,触发rdb持久化分为手动触发和自动触发

触发机制
手动触发对应的命令save和bgsave
  • save:阻塞当前redis服务,知道rdb的过程完成为止,对于内存比较大的数据或者实例会造成上时间的堵塞

  • bgsave:redis进程会fork一个子进程,rdb持久化过程由子进程负责,完成后自动结束。阻塞只会发生在fork阶段,时间一般都很短

自动触发
  • 使用save的相关配置,如"save m n" 表示在m秒内数据存在n次修改时,会自动触发bgsave

  • 如果从节点执行完全复制操作,主节点自动执行bgsave生成rdb文件并发送给从节点

  • 执行debug reloade 命令重新加载redis时,也会自动触发save操作

  • 默认情况下执行shutdown 命令时,如果没有开启aof持久化时,则自动执行bfsave。

rdb流程

  1. 执行bgsave命令,redis父进程会判断当前是否有正在执行的子进程,如果有就直接返回

  2. 父进程执行fork一个子进程,在fork过程中父进程会阻塞,可以通过 info stats命令,查看_fork_usec,可以获取最近一个fork的耗时记录

  3. 父进程fork完成后,bgsave会返回一个信息,父进程可以继续响应其他的命令

  4. 子进程创建rdb文件,根据父进程内存生成临时的快照文件,完成后会对原文件进行原子替换

  5. 子进程发送信号给父进程表示完成

优缺点
rdb优点
  • rdb是一个紧凑的二进制文件,代表redis在某个时间点上的数据快照,适合做数据备份,全量复制等场景

  • redis在加载rdb恢复数据远远快于aof的方式。

rdb缺点
  • rdb没有办法对数据做到实时或者秒级持久化,每次都要fork操作创建子进程,属于重量级操作

AOF

aof以独立日志的方式记录每次写命令(不是数据,而是命令),重启时再重新执行aof文件中的命令用于恢复数据的目的。aof也解决了rdb无法实时或者秒级操作的处理。

aof使用

开启aof需要在配置文件中配置:appendonly yes,默认是关闭的状态。aof文件名appendfilename配置,默认是的是appendonly.aof

aof的工作流程:命令写入(append)文件同步(sync)文件重写(rewrite)重启加载(load)

  1. 所有的写入命令会追加到aof_buf中

  2. aof_buf 根据对应的策略向硬盘做同步操作

  3. 随着aof文件越来越大,需要定期的对aof文件重写,压缩文件

  4. 当redis服务器重启时,可以加载aof文件进行数据恢复

命令写入(append)

aof命令写入的内容是以文本协议格式

aof为什么使用文本协议格式

  • 文本协议具有很好的兼容性

  • 所有的写入命令包括追加操作,用文本协议格式,避免了二次处理开销

  • 文本协议具有可读性,方便修改和处理

aof为什么要把命令追加到aof_buf中

  • redis使用单线程方式处理命令,如果每次写aof文件命令都会直接追加到硬盘,性能完全取决于当前硬盘的负载
文件同步

redis提供了多种奥法缓冲区同步文件策略,由appendfsync参数控制

  1. everysec:命令写入aof_buf后调用系统write操作,write完成后线程返回。fsync同步操作,由专门线程每秒调用一次

  2. always:命令写入aof_buf后调用系统fsync操作,同步到aof文件,fsync完成后线程返回

  3. no:命令写入aof_buf后调用系统write操作,不对aof文件做同步操作,同步硬盘操作由操作系统负责,同步周期最长为30秒

  • 配置为everysec,是默认配置,也是最优的同步策略,但是在系统宕机的情况下理论理论情况下会丢失1秒的数据,实际上最多丢失2秒

  • 配置为always,每次写入都要同步aof文件,会降低redis高性能特性,不建议配置

  • 配置为no,由于每次同步aof文件的时间是不确定的,而且会加大每次同步硬盘的数据量,但是数据不发保证安全性

重写机制

随着命令的不断写入到aof中,文件会越来越大,为了解决这个问题,redis对aof引入了重写机制压缩文件的大小。aof重写是把redis进程内的数据转换为写命令同步到新的aof文件的过程

aof重写后文件变小的原因大概有三点
  1. 进程内已经超时的数据不写入文件

  2. 旧的aof文件中,包含无效了命令,如del hdel等,重写使用进程内数据直接生成,aof文件只保留最终写入数据的命令

  3. 多条命令可以合成一个命令

aof重写的过程可以手动和自动触发

手动触发:直接调用bgrewriteaof命令

自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机

auto-aof-rewrite-min-size:表示aof重写时文件文件最小体积,默认为64mb

auto-aof-rewrite-percentage:代表当前aof文件空间和上一次重写后的aof文件空间的比值

自动触发时机 = aof_current_size > auto-aof-rewrite-min-size && (aof_current_size-aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage

流程说明:
  1. 执行aof重写

  2. 父进程执行fork创建子进程

  3. 主进程fork子进程后,继续响应其他的命令,所有的又该命令依旧写入aof缓冲区中,并根据appendfsync策略同步到硬盘中,保证原有aof机制的正确性

  4. 由于fork操作运用写时复制技术,子进程只能共享fork操作时的内存数据,由于父进程依旧响应命令,所以redis会保存这部分命令,防止新的aof文件生成期间丢失这部分的命令

  5. 子进程根据内存快照,按照命令合并规则写入到新的aof文件,每次批量写入硬盘数据量由配置 aof-rewrite-incremental-fsync控制,防止单次刷盘数据过多造成硬盘阻塞

  6. 新aof文件写入完成后,子进程发送信号给父进程

  7. 父进程再把aof重写缓冲区的数据写入到新的aof文件中

  8. 使用新的aof文件替换老文件,就完成aof重写

重启加载

aof和rdb都是用于服务器重启时恢复数据

流程说明
  1. aof持久化开启并存在aof文件时,优先加载aof文件,日志:append only

  2. aof没有开启时且存在rdb文件,就加载rdb文件,日志:disk

  3. 加载文件成功后,redis启动,加载失败,则启动失败

AOF追加阻塞

开启aof持久化时,默认的同步策略everysec,当系统资源资源繁忙时,会造成reids主线程阻塞

阻塞流程

  1. 主线程负责写入aof缓冲区

  2. aof线程负责每秒执行一次同步磁盘操作,并记录最近一次同步时间

  3. 主线程负责对比上一次aof同步时间

  • 如果距上次同步成功时间在2秒内,主线程直接返回

  • 如果距上次同步成功时间超过2秒,主线程将会阻塞,直到同步操作完成

仅供自己学习使用,如有侵权,请及时联系我删除

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值