Redis的RDB和AOF

Redis的RDB和AOF

1、概述

Redis 提供了两种持久化方式:RDB和AOF
RDB使用一次生成内存快照的方式,产生的文件紧凑压缩比更高,因此读取RDB恢复速度更快,由于每次生成RDB开销较大,无法做到实时持久化,一般用于数据冷备和复制传输
AOF持久化 以独立日志的方式记录每次写命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的。AOF主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式

2、RDB

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
Redis会单独创建(fork)一个子进程来进行持久化,会将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化后的数据可能丢失,Redis默认的就是RDB
rdb保存的文件是dump.rdb 在dbfilename中配置
在这里插入图片描述

2.1、RDB的触发机制

  1. 手动触发save命令
    save命令会阻塞当前Redis服务器,直到RDB完成,对于内存较大的实例会造成长时间阻塞不建议线上环境使用
  2. 手动触发bgsave命令
    Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,阻塞只发生在fork阶段
  3. 自动触发
    1、使用save相关配置 “save m n” 表示在m秒内数据集存在n次修改自动触发bgsave
    2、从节点执行全量复制操作
    3、执行debug reload命令重新加载Redis时
    4、默认情况下执行 shutdown 命令,并且没有开启AOF持久化功能时

2.2、bgsave触发流程

在这里插入图片描述
1 ) 执行bgsave 命令,redis父进程判断当前是否存在正在执行的进程(RDB/AOF) 存在直接返回

2)父进程执行fork操作创建子进程,fork会发生阻塞

3)父进程fork完成后,bgsave命令返回“background saving started”信息并不会阻塞进程,可以继续响应其他命令

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

5)进程发送信号给父进程表示江湾城,父进程更新统计信息

Redis默认采用LZF算法对成圣的RDB文件做压缩处理,压缩后的文件远远小于内存大小

2.3、RDB的优点

1、RDB是紧凑压缩的二进制文件,代表Redis早某个时间点上的数据快照,非常适合用于备份,全量复制的场景
2、Redis加载RDB恢复数据远远快于AOF

2.4、RDB的优点

1、RDB的方式数据没办法做到持久化/秒级持久化。
2、RDB文件使用特定二进制保存,Redis版本演变过程有多个格式的RDB。存在不兼容问题

3、AOF

3.1、AOFAOF工作流程

在这里插入图片描述

​ 1)所有的命令都会追加到aof_buf(缓冲区)中

​ 2)AOF缓冲区根据对赢得策略向硬盘做同步策略

​ 3)随着AOF文件越来越大,定期对AOF进行重写

​ 4) Redis重启时,加载AOF文件进行数据恢复

3.2 命令写入

AOF命令写入直接用的是文本协议格式,文本协议有较好的兼容性,开启AOF之后所有命令写入直接采用文本协议避免了二次开销,文本协议具有可读性,方便修改和处理

​ Redis把命令追加到缓冲区的好处:Redis使用单线程响应命令,如果吧AOF文件命令直接追加到硬盘,性能完全取决于当前硬盘的负载,Redis可以提供多种缓冲区同步硬盘策略,可以再性能和安全方面做出平衡

3.3 文件同步

在这里插入图片描述

同步设置 appendfsync no/always/everysec

no: don’t fsync, just let the OS flush the data when it wants. Faster.
always: fsync after every write to the append only log. Slow, Safest.
everysec: fsync only one time every second. Compromise.

配置为no,由于操作系统每次同步AOF文件的周期不可控,而且会加大每次同步硬盘的数据量,虽然提升了性能,但数据安全性无法保证。

配置为always时,每次写入都要同步AOF文件,在一般的SATA硬盘上,Redis只能支持大约几百TPS写入,显然跟Redis高性能特性背道而驰,不建议配置

配置为everysec,是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性。理论上只有在系统突然宕机的情况下丢失1秒的数据。

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

no:命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30s

​write操作会触发延迟写(delayed write)机制,Linux在内核提供页缓冲区用来提高硬盘IO性能,write操作在写入系统缓冲区后直接返回,同步硬盘操作依赖于系统调度机制,例如:缓冲区页空间写满或达到特定时间周期。同步文件之前,如果此时系统故障宕机,缓冲区内数据将丢失。

​fsync针对单个文件操作(比如AOF文件),做强制硬盘同步,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化

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

3.4 重写规则说明

在这里插入图片描述
如果aop文件大于64M,太大了!fork一个新的进程来将我们的文件进行重写

4、扩展

  1. RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储
  2. AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
  3. 只做缓存,如果你只希望你的数据在服务器运行的时候存在,完全可以不用任何持久化
  4. 同时开启两种持久化方式
  • 在这种情况下,当redis重启的时候会优先加载AOF文件来恢复数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
  • RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段
  1. 性能建议
  • 因为RDB文件只用作后背用途,建议旨在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则
  • 如果Enable AOF,好处是在最恶劣情况下也只会丢失不超过两秒的数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewriter过程中产生的新数据写到新文件造成的阻塞是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以射到5G以上,默认超过原大小100%大小重写可以改到适当的数值
  • 如果不Enable AOF,仅靠Master-Slave Repllcation实现高可用也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较Master/slave中的RDB文件,载入较新的那个,微博就是这种架构

5、鸣谢

本文转载自:
1.https://blog.nowcoder.net/n/63c9812ce634474280675f3f6bb4d1ca
2.狂神说:https://www.kuangstudy.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值