Redis持久化方式

Redis的持久化包括RDB和AOF两种方式。RDB通过快照保存数据,优点是文件小、恢复快,但可能导致数据丢失。AOF记录写操作日志,保证数据完整性,支持不同的fsync策略,但体积大、恢复慢。AOF重写用于压缩文件。混合持久化结合RDB和AOF的优点,减少数据丢失。

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

RDB(Redis Database)

将当前时间点所有数据集通过快照的形式保存到磁盘中。它是Redis默认开启的持久化方式,数据以二进制的形式写入磁盘中,默认文件名为dump.rdb。

RDB 的触发有三种机制,执行save命令、执行bgsave命令、在redis.config中配置自动化。

1、save

Redis是单线程的,而save命令会阻塞主线程,在执行该命令期间,Redis无法处理其他的命令,直到整个RDB过程完成为止,当这条指令执行完毕,将RDB文件保存下来后,才能继续去响应请求。这种方式用于新机器上数据的备份还好,如果用在生产上,那么简直是灾难,数据量过于庞大,阻塞的时间点过长。这种方式并不可取。

2、bgsave

bgsave通过fork一个子进程(fork时阻塞主线程),然后通过这个子进程来处理接下来所有的保存快照工作,父进程就可以继续响应客户端请求。

3、redis.config配置

上述两种方式都需要我们在客户端中去执行save或者bgsave命令,在生产情况下我们更多地需要是自动化的触发机制,那么Redis就提供了这种机制,我们可以在redis.config中对持久化进行配置,来实现每隔一段时间自动执行一次 bgsave 命令:

# 900 秒内,如果有一个或一个以上的修改操作,那么就自动进行一次自动化备份
save 900 1
# 300 秒内如果有十次或以上的修改操作,那么就进行数据备份
save 300 10
# 60 秒内如果有一万次或以上的修改操作,那么就进行数据备份
save 60 10000

4、RDB优缺点

优点:

1、体积更小:相同的数据量rdb数据比aof的小,因为rdb是紧凑型二进制文件

2、恢复更快:因为rdb是数据的快照,基本上就是数据的复制,不用重新读取再写入内存

3、性能更高:父进程在保存rdb时候只需要fork一个子进程,无需父进程的进行其他io操作,也保证了服务器的性能

缺点:

1、故障丢失:RDB 快照是全量快照的方式,所以执行的频率不能太频繁,否则会影响 Redis 性能,因此在服务器发生故障时,丢失的数据会比 AOF 持久化的方式更多

2、耐久性差:相对AOF的异步策略来说,因为RDB的复制是全量的,即使是fork的子进程来进行备份,当数据量很大的时候对磁盘的消耗也是不可忽视的,尤其在访问量很高的时候,fork的时间也会延长,导致cpu吃紧,耐久性相对较差。

AOF(Append Only File)

是一种保存写操作命令到日志的持久化方式

Redis会在收到客户端修改指令后,进行参数修改、逻辑处理,如果没有问题,就立即将该指令文本存储到 AOF 日志中,也就是说,先执行指令才将日志存盘。

为了提高文件的写入效率,在现代操作系统中,当用户调用 write 函数时,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁盘里面。

1、aof持久化配置(appendfsync)

  • Always,每次写操作命令执行完后,同步将 AOF 日志数据写回硬盘;

  • 可以最大程度保证数据不丢失,但是由于它每执行一条写操作命令就同步将 AOF 内容写回硬盘,所以是不可避免会影响主进程的性能。

  • Everysec,每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘;

  • 如果上一秒的写操作命令日志没有写回到硬盘,服务器发生了宕机,这一秒内的数据自然也会丢失。

  • No,每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘。

  • 操作系统写回硬盘的时机是不可预知的,如果 AOF 日志内容没有写回硬盘,一旦服务器宕机,就会丢失不定数量的数据。

这三种策略只是在控制 fsync() 函数的调用时机

如果想要应用程序向文件写入数据后,能立马将数据同步到硬盘,就可以调用 fsync() 函数,这样内核就会将内核缓冲区的数据直接写入到硬盘,等到硬盘写操作完成后,该函数才会返回。

  • Always 策略就是每次写入 AOF 文件数据后,就执行 fsync() 函数;

  • Everysec 策略就会创建一个异步任务来执行 fsync() 函数;

  • No 策略就是由操作系统来控制何时执行 fsync() 函数。

2、AOF 重写机制

Redis 为了避免 AOF 文件越写越大,提供了 AOF 重写机制,当 AOF 文件的大小超过所设定的阈值后,Redis 就会启用 AOF 重写机制,来压缩 AOF 文件。

# 开启重写机制
no-appendfsync-on-rewrite yes 
# 比上次从写后文件大小增长了100%再次触发重写
auto-aof-rewrite-percentage 100 
# 当文件至少要达到64mb才会触发制动重写
auto-aof-rewrite-min-size 64mb 

AOF重写:主进程fork出一个子进程,子进程创建出aof重写缓冲区,并执行aof重写, 当一个 redis 命令被服务进程接收且需要被执行时,除了执行这个命令之外,同时还会将这个命令发送给 AOF 缓冲区和 AOF 重写缓冲区。 当子进程完成 AOF 重写后,它会向父进程发送一个信号,要求父进程调用一个信号处理函数: 首先阻塞主服务进程,将 AOF 重写缓冲区的内容写入到新的 AOF 文件中。 其次新的 AOF 覆盖旧的 AOF。 最后恢复主服务进程,可以继续接收并执行 redis 命令。

3、为什么重写 AOF 的时候,不直接复用现有的 AOF 文件,而是先写到新的 AOF 文件再覆盖过去呢?

因为如果 AOF 重写过程中失败了,现有的 AOF 文件就会造成污染,可能无法用于恢复使用。

所以 AOF 重写过程,先重写到新的 AOF 文件,重写失败的话,就直接删除这个文件就好,不会对现有的 AOF 文件造成影响。

4、AOF 的优缺点

优点:

1.数据保证:我们可以设置fsync策略,一般默认是everysec,也可以设置每次写入追加,所以即使服务死掉了,最多丢失一秒数据

2.自动缩小:当aof文件大小到达一定程度的时候,后台会自动的去执行aof重写,此过程不会影响主进程,重写完成后,新的写入将会写到新的aof中,旧的就会被删除掉。但是此条如果拿出来对比rdb的话还是没有必要算成优点,只是官网显示成优点而已。

缺点:

1.性能相对较差:它的操作模式决定了它会对redis的性能有所损耗

2.体积相对更大:尽管是将aof文件重写了,但是毕竟是操作过程和操作结果仍然有很大的差别,体积也毋庸置疑的更大。

3.恢复速度更慢

混合持久化

# 开启混合持久化功能
aof-use-rdb-preamble yes 

重启 Redis 时,如果使用 RDB 来恢复内存,会丢失大量数据。而如果只使用 AOF 日志重载,那么效率又太过于低下。Redis 4.0 提供了混合持久化方案,将 RDB 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自 RDB 持久化开始到持久化结束这段时间发生的增量 AOF 日志,通常这部分日志很小。

混合持久化工作在 AOF 日志重写过程

  1. 当开启了混合持久化,在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件

  1. 然后主线程处理的写操作命令会被记录在重写缓冲区中,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件

  1. 写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的 AOF 文件。

也就是说,使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据。这样做的好处在于,重启 Redis 加载数据时,由于前半部分是 RDB 内容,这样加载的时候速度会很快。加载完 RDB 的内容后,才会加载后半部分的 AOF 内容,这里的内容是 Redis 后台子进程重写 AOF 期间,主线程处理的写操作命令,可以使得数据更少的丢失

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值