【Redis】持久化操作

Redis 提供了2个不同形式的持久化方式。

  • RDB(Redis DataBase)
  • AOF(Append Of File)

RDB

RDB全称叫做Redis DataBase。在指定的时间间隔内将内存中的数据集快照写入磁盘。

如何进行备份?

Redis会fork一个子进程来进行持久化;

  • 会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。
  • 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。
  • 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

image-20221214233938144

快照的使用

Redis 提供了两个命令来生成 RDB 文件,分别是 savebgsave,他们的区别就在于是否在「主线程」里执行:

  • 执行了 save 命令,就会在主线程生成 RDB 文件,由于和执行操作命令在同一个线程,所以如果写入 RDB 文件的时间太长,会阻塞主线程;
  • 执行了 bgsave 命令,会创建一个子进程来生成 RDB 文件,这样可以避免主线程的阻塞;

Redis 还可以通过配置文件的选项来实现每隔一段时间自动执行一次 bgsave 命令,默认会提供以下配置:

save 900 1
save 300 10
save 60 10000

虽然是save命令,但是实际上执行的是bgsave命令。只要满足上面条件的任意一个,就会执行 bgsave,它们的意思分别是:

  • 900 秒之内,对数据库进行了至少 1 次修改;
  • 300 秒之内,对数据库进行了至少 10 次修改;
  • 60 秒之内,对数据库进行了至少 10000 次修改。
vim /opt/redis/redis.conf

image-20221215000000011

默认生成的文件名和文件路径:

image-20221215000154023

在/usr/local/bin目录下,存在dump.rdb文件

image-20221215001420974

其他配置信息

  • stop-writes-on-bgsave-error;当Redis无法写入磁盘的话,直接关掉Redis的写操作。推荐yes.
  • rdbcompression压缩文件;对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。
  • rdbchecksum 检查完整性;在存储快照后,还可以让redis使用CRC64算法来进行数据校验。

RDB备份

先通过config get dir 查询rdb文件的目录,将*.rdb的文件拷贝到别的地方

rdb的恢复

  • 关闭Redis
  • 先把备份的文件拷贝到工作目录下 cp dump2.rdb dump.rdb
  • 启动Redis, 备份数据会直接加载

RDB的优劣势

优势:

  • 适合大规模的数据恢复
  • 对数据完整性和一致性要求不高更适合使用
  • 节省磁盘空间
  • 恢复速度快

劣势:

  • Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
  • 虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
  • 在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。

AOF

AOF全称是Append Only File。以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录)。

  • 只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据;
  • 换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

image-20221215111929889

AOF流程

(1)客户端的请求写命令会被append追加到AOF缓冲区内;

(2)AOF缓冲区根据AOF持久化策略[always,everysec,no]使用fsync操作刷新缓冲区数据同步到磁盘的AOF文件中;

(3)AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;

(4)Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的

image-20221215112815454

Redis 是先执行写操作命令后,才将该命令记录到 AOF 日志里的。

优势:

  • 避免额外的开销。AOF只有在命令执行成功后,才会将命令记录在AOF日志中。
  • 不会阻塞当前写操作命令执行。因为当写操作命令执行成功后,才会将命令记录到 AOF 日志。

劣势:

  • 存在数据丢失的风险:执行写操作和记录日志是两个过程。如果在写操作结束,记录日志前,Redis发生宕机,这条命令就会丢失。
  • 可能阻塞下一条命令:将命令写入到日志的这个操作也是在主进程完成的。如果在将日志内容写入磁盘时,服务器的I/O压力过大,则写入磁盘操作就可能被阻塞,从而阻塞Redis的下一条命令。

AOF配置

AOF默认不开启,需要在redis.conf中配置想要的命令。

appendonly yes

image-20221215113954254

文件路径和RDB文件路径一样,都在当前工作路径生成。

AOF恢复

AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。

  • 修改默认的appendonly no,改为yes
  • 将有数据的aof文件复制一份保存到对应目录(查看目录:config get dir)
  • 恢复:重启redis然后重新加载

AOF写回策略

Redis写入日志流程:

  1. Redis 执行完写操作命令后,会将命令追加到 server.aof_buf 缓冲区;
  2. 然后通过 write() 系统调用,将 aof_buf 缓冲区的数据写入到 AOF 文件,此时数据并没有写入到硬盘,而是拷贝到了内核缓冲区 page cache,等待内核将数据写入硬盘;
  3. 具体内核缓冲区的数据什么时候写入到硬盘,由内核决定。

image-20221215114554331

Redis提供了三种写入磁盘的策略,分别是:

  • appendfsync always:始终同步,每次Redis的写入都会立刻记入日志;因为每一条命令都需要写入日志,主进程负担加大,性能较差但数据完整性比较好。
  • appendfsync everysec:每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
  • appendfsync no:redis不主动进行同步,把同步时机交给操作系统。操作系统写回硬盘的时机是不可预知的,如果 AOF 日志内容没有写回硬盘,一旦服务器宕机,就会丢失不定数量的数据。

image-20221215115015405

内核中如何实现不同的写回策略?

实现不同的写回策略关键是如何调用fsync函数。

#include<unistd.h>
int fsync(int fd);
  • fsync系统调用:需要你在入参的位置上传递给他一个fd,然后系统调用就会对这个fd指向的文件起作用。
  • fsync会确保一直到写磁盘操作结束才会返回,所以当你的程序使用这个函数并且它成功返回时,就说明数据肯定已经安全的落盘了

image-20221215115526741

Always策略:每次写入AOF文件后,就调用fsync()函数刷新到磁盘

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

No策略:不执行fsync()函数,,由内核发起刷新缓冲区操作

rewrite重写机制

AOF采用文件追加方式,文件会越来越大。为避免出现此种情况,新增了重写机制:

  • 当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集。

AOF 重写机制的过程:

是在重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到新的 AOF 文件,等到全部记录完后,就将新的 AOF 文件替换掉现有的 AOF 文件。

image-20221215120842439

重写工作完成后,就会将新的 AOF 文件覆盖现有的 AOF 文件,这就相当于压缩了 AOF 文件,使得 AOF 文件体积变小了。

AOF后台重写

在触发 AOF 重写时,比如当 AOF 文件大于 64M 时,就会对 AOF 文件进行重写,这时是需要读取所有缓存的键值对数据,并为每个键值对生成一条命令,然后将其写入到新的 AOF 文件,重写完后,就把现在的 AOF 文件替换掉。

重写的过程是非常耗时的,所以重写的操作不能放在主进程里。

Redis 的重写 AOF 过程是由后台子进程 bgrewriteaof 来完成的

  • 进程进行 AOF 重写期间,主进程可以继续处理命令请求,从而避免阻塞主进程
  • 子进程带有主进程的数据副本,通过fork产生一个子进程。

混合持久化

混合持久化,也就是混合使用 AOF 日志和RDB快照

如果想要开启混合持久化功能,可以在 Redis 配置文件将下面这个配置项设置成 yes:

aof-use-rdb-preamble yes

image-20221215163754654

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

  • 当开启了混合持久化时,在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件;
  • 随后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件;
  • 写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。

image-20221215164059618

优势

  • 前半部分数据是RDB内容,所以数据加载的速度较快
  • 加载完RDB的内容后,才会加载后半部分的 AOF 内容;AOF的内容是 Redis 后台子进程重写AOF期间,主线程处理的操作命令,可以使得数据更少的丢失
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

影中人lx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值