Redis的持久化(RDB和AOF)--详解

本文深入解析Redis的两种主要持久化方案:RDB和AOF。RDB通过快照在特定时间点保存数据集,而AOF则记录每次操作,确保数据的完整性。文章探讨了它们的优缺点及配置细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis的持久化

1.Redis的持久化方案

由于redis的数据都存储在内存中,如果没有配置持久化,redis重启之后数据就会全部丢失,于是需要redis的持久化功能,将数据保存到磁盘中,在redis重启后,就会从磁盘中恢复数据

从严格意义上说,Redis服务提供四种持久化存储方案:RDB、AOF、虚拟内存(VM)和 DISKSTORE。虚拟内存(VM)方式,从Redis Version 2.4开始就被官方明确表示不再建议使用,Version 3.2版本中更找不到关于虚拟内存(VM)的任何配置范例

RDB:在指定的时间间隔,对内存中的数据进行快照存储,原理是将redis在内存中的数据定时dump到磁盘上的dump.rdb进行持久化
AOF:记录每一次对服务器的操作,相当于日志的形式持久化数据,原理是Redis的操作日志以追加的形式写入文件。

2.RDB

RDB 持久化是在指定时间间隔内将内存中的数据写入磁盘,实际操作过程是fork(开辟)一个子进程,先将数据集写入临时文件,写入成功之后,再替换之前的文件,用二进制压缩进行存储

在这里插入图片描述
讲解一下图的执行流程

1:当达到快照的条件的时候(或者手动进行触发save(堵塞,执行save期间,redis不能操作其他的指令,耗费性能,不使用)/ bgsave(执行该命令的时候,Redis后台fork一个子进程,只会在fork期间堵塞) )进行触发RDB持久化
2:redis会fork(开辟)一个子进程
3.1:子进程将redis内存区域的数据压缩到一个临时的rdb文件中,然后进行替换原先的rdb文件,完成对新数据的持久化,快照进程结束
3.2:在子进程执行的时候回copy出一个新的内存区域B,这时候操作的数据会存放在B内存中,直到快照结束的时候才会将变更写入到原始的内存中。

问题:

在进行快照操作的这段时间,如果发生服务崩溃怎么办?
在快照操作没有完成之前(临时文件没有压缩替换完成之前),原始的rdb文件是不会变更的,如果服务出现崩溃,就会用原始的rdb文件进行恢复。也就是快照子进程会创建一个临时文件进行接收压缩的数据,等待压缩完成之后才会替换原先的rdb文件。

下面是rdb配置的主要信息

# 周期性执行条件的设置格式为
save <seconds> <changes>
# 默认的设置为:
save 900 1             # 如果900秒中有1条key发生变化,开始快照
save 300 10            # 如果300秒中有10条key发生变化,开始快照
save 60 10000          # 如果60秒中有10000条key发生变化,开始快照
# 以下设置方式为关闭RDB快照功能
save ""

3.AOF

由于RDB是一定时间间隔内进行快照,对于重要的数据,RDB在发生服务器崩溃的时候常常会丢失最近一批更新的数据。如果数据非常的庞大,在快照的时候cpu会讲资源用到快照的操作上去,就会降低redis的性能

AOF方式的核心思想就是:
记录Redis服务启动成功后的每一次影响数据状态的操作命令,以便在Redis服务异常崩溃的情况出现时,可以按照这些操作命令恢复数据状态。
这样一直记录操作,AOF文件会越来越大,不会降低恢复的难度吗?
在这里插入图片描述
AOF提供了一种解决办法,AOF的重写 最终的目的是记录每一条数据最终的一种状态,比如我对一个key做了好多次操作,他会将每一次的操作记录到aof中,这是没有必要的,我没做持久化只是为了数据的恢复,没有必要清除数据的操作过程,那么记录数据的最终结果就可以了,这就是AOF的重写

redis的config中有这样一个参数

appendfsync:这个参数项是AOF功能最重要的设置项之一,主要用于设置“真正执行”操作命令向AOF文件中同步的策略。

什么叫“真正执行”呢?还记得Linux操作系统对磁盘设备的操作方式吗? 为了保证操作系统中I/O队列的操作效率,应用程序提交的I/O操作请求一般是被放置在linux Page Cache中的,然后再由Linux操作系统中的策略自行决定正在写到磁盘上的时机。而Redis中有一个fsync()函数,可以将Page Cache中待写的数据真正写入到物理设备上,而缺点是频繁调用这个fsync()函数干预操作系统的既定策略,可能导致I/O卡顿的现象频繁 。

appendfsync他可以设置三个值分别为 :always、everysec、no,默认的值为everysec。

always:会使得AOF对数据的保存非常稳健。其设置意义是只要有一个写操作命令执行成功,就执行一次fsync函数调用。所以很显然always的设定值,就是三个选项值中处理效率最慢的。

no:这个设置值表示Redis不会将执行成功的操作命令正真刷入AOF文件,而是完成操作系统级别的写操作后就认为AOF文件记录成功了,后续的I/O操作完全依赖于操作系统的设定,一般30秒会刷一次。

everysec:这是默认的设置值,也是可以在数据稳健性和性能上平衡较好策略。它表示每秒钟都做一次fsync函数调用,正真做AOF文件的写入操作。

有什么不对的请指出,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值