【Redis】AOF持久化机制


在这里插入图片描述

什么是AOF?

Redis AOF(Append-Only File)持久化是一种将每个写操作以追加的方式写入日志文件的机制,用于记录数据库的命令和数据修改操作。它可以保证数据在系统重启或崩溃后的持久化和恢复。将Redis内存中的数据持久化到磁盘中,一般用于系统重启或崩溃之后的数据恢复,为数据提供保障。

如何开启AOF/如何配置Redis使用AOF持久化?

AOF是默认开启的吗?

在Redis中,AOF(Append-Only File)持久化在默认情况下是关闭的。

开启Redis的AOF持久化步骤

  1. 打开Redis的配置文件(redis.conf):

$ sudo nano /path/to/redis.conf

  1. 在配置文件中找到以下行(可能在注释行中):

\# appendonly no

  1. 将该行的注释去掉,并将选项值从 “no” 改为 “yes”:

appendonly yes

  1. 保存配置文件并关闭编辑器。
  2. 重启Redis服务器,使配置生效。

AOF持久化基本流程

在这里插入图片描述

1、客户端发送命令,redis接收并进行写操作。

2、redis将写操作追加到AOF缓存区中,不会立即将其写入到AOF文件中。

3、将AOF缓存区中数据写入到AOF日志文件中(持久化到磁盘的时间是操作系统决定,我们只能决定什么时候进行写入)

为什么需要AOF缓存区?

  1. 提高性能:AOF缓冲区允许Redis将写操作首先写入内存中的缓冲区,而不是直接写入AOF文件。由于内存操作速度较快,将写操作暂时存储在AOF缓冲区中可以提高Redis的写入性能。
  2. 减少磁盘I/O:将写操作先写入AOF缓冲区,而不是直接写入AOF文件,可以减少磁盘I/O的频率。较少的磁盘写入操作可以降低磁盘的负载,提高整体系统性能。
  3. 批量写入:AOF缓冲区允许Redis将多个写操作合并为一个较大的写入操作。这样可以减少写入AOF文件的次数,提高写入效率。
  4. 减少AOF文件碎片:通过将多个写操作合并为一个写入操作,AOF缓冲区可以减少AOF文件的碎片化。碎片化的AOF文件可能会导致文件过大和读取性能下降,而AOF缓冲区可以一定程度上减轻这个问题。
  5. 容错能力:AOF缓冲区可以帮助Redis在发生故障或崩溃时提供一定的容错能力。即使Redis崩溃,AOF缓冲区中的写操作仍然存在,并可以用于恢复数据库状态

如何处理AOF文件过大的问题?

AOF的重写机制

如何/怎样触发AOF的重写机制?

1、通过手动的方式触发重写 bgrewriteaof

2、自动触发:Redis还提供了自动触发AOF重写的机制。可以通过以下两个配置选项来配置自动触发的条件:

  • auto-aof-rewrite-percentage:指定AOF文件的大小相对于上一次重写时的大小增长百分比。当AOF文件的大小增长超过设定的百分比时,触发自动AOF重写。默认值为100(即AOF文件大小翻倍时触发)。
  • auto-aof-rewrite-min-size:指定AOF文件的最小大小,以MB为单位。当AOF文件的大小超过设定的最小大小,并且增长超过auto-aof-rewrite-percentage所设定的百分比时,触发自动AOF重写。默认值为64MB。
主进程在子进程执行AOF重写期间

1、执行客户端发送过来的命令。

2、将命令追加到AOF缓存区。

3、将命令追加到AOF重写缓存区。

子进程重写操作过程:

AOF重写实际上是主进程fork()出一个重写子进程进行重写操作,实际重写操作过程如下:

1、主进程在通过fork系统调用生成 bgrewriteaof 子进程

2、子进程读取数据,这里会运用到我们上面所讲的压缩机制,对数据或命令进行重写。

3、将重写的aof文件替换掉原有的aof文件。

当子进程完成 AOF 重写工作(扫描数据库中所有数据,逐一把内存数据的键值对转换成一条命令,再将命令记录到重写日志)后,会向主进程发送一条信号,信号是进程间通讯的一种方式,且是异步的。

主进程收到该信号后,会调用一个信号处理函数,该函数主要做以下工作:

将 AOF 重写缓冲区中的所有内容追加到新的 AOF 的文件中,使得新旧两个 AOF 文件所保存的数据库状态一致;

新的 AOF 的文件进行改名,覆盖现有的 AOF 文件。

信号函数执行完后,主进程就可以继续像往常一样处理命令了。

压缩机制

1、第一种方式 直接根据Redis存储的数据进行反推存入到AOF重写缓存中

2、如果命令连续的话,会进行语义分析,对命令进行简化,例如:lpush hhk A B,lpush hhk C D,rpop hhk,rpop hhk只存lpush hhk C D

在这里插入图片描述

写时复制

写时复制通过共享物理内存的方式,提高读取效率。在进行重写的过程中,父子进程会共享物理内存,不过这个共享的内存只能以只读的方式。

主进程在通过 fork 系统调用生成 bgrewriteaof 子进程时,操作系统会把主进程的页表复制一份给子进程。两者的虚拟空间不同,但其对应的物理空间是同一个。(这样可以节约物理内存资源)

页表记录着虚拟地址和物理地址映射关系。当父进程或者子进程在向这个内存发起写操作时,会触发写时复制(注意这里只会复制主进程修改的物理内存数据,没修改物理内存还是与子进程共享的,复制物理内存数据时会阻塞父进程)

AOF重写缓存区的作用

子进程在重写过程,主进程也是在运行并且接收客户端的读写命令,会对缓存中的数据进行一些更新操作。当Redis主进程对内存中的数据A进行修改操作,假设数据A已经被子进程进行了重写,就会出现持久化的数据与内存数据不一致的情况,此时我们的AOF重写缓存区就出现了,它就是用来解决上述的问题。

AOF重写缓存区是在AOF重写过程中使用的临时存储区域,它不会持久化到磁盘上。一旦AOF重写完成,缓冲区中的数据就会被写入新生成的AOF文件,并替换原始的AOF文件。

问题:重写过程中,Redis既存放在【AOF缓冲区】又存放在【AOF重写缓冲区】,那么当子进程完成重写操作,并将重写缓冲区中的命令追加到AOF文件中,此时AOF缓冲区里面也有同样的命令,会不会造成重复插入?

在AOF重写完成后,Redis会继续正常地将写入命令追加到AOF缓冲区中,并将其写入新的AOF文件中。在这个过程中,Redis会确保不会出现重复的命令写入到AOF文件中。

Redis在AOF重写过程中会维护一个偏移量(offset),表示重写过程中已经处理的命令数量。当新的写入命令被追加到AOF缓冲区时,Redis会根据当前的偏移量,跳过已经在AOF重写缓冲区中的命令,以避免重复写入。

因此,尽管AOF缓冲区可能包含AOF重写缓冲区中的命令,Redis会通过偏移量来确保在下一次写入AOF文件时不会重复写入相同的命令。

需要注意的是,这种处理方式要求AOF重写过程完成后,新的写入命令必须与重写期间的命令相同。如果在AOF重写完成之前,Redis服务器重新启动或发生崩溃,AOF缓冲区中的新写入命令可能会被丢失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值