Redis持久化

1. 为什么需要持久化?

因为Redis是内存数据库,它将自己的数据存储在内存里面,一旦Redis服务器进程退出或者运行Redis服务器的计算机停机,Redis服务器中的数据就会丢失。

为了避免数据丢失,所以Redis提供了持久化机制,将存储在内存中的数据保存到磁盘中,用于在Redis服务器进程退出或者运行Redis服务器的计算机停机导致数据丢失时,快速的恢复之前Redis存储在内存中的数据。

Redis提供了2种持久化方式,分别为:

RDB持久化
AOF持久化

接下来,我们一一详解。

2. RDB持久化

RDB持久化是将某个时间点上Redis中的数据保存到一个RDB文件中,基于RDB持久化的上述性质,所以RDB持久化也叫做快照持久化,如下所示:
基于RDB持久化的上述性质,所以RDB持久化也叫做快照持久化。
该文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时Redis中的数据,如下所示:
在这里插入图片描述

2.1 创建RDB文件

Redis提供了2个命令来创建RDB文件,一个是SAVE,另一个是BGSAVE。

SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求。

BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求。

因为BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以推荐使用BGSAVE命令。

我们可以手动执行该命令,如上面截图所示,但还是推荐设置下Redis服务器配置文件的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。

我们可以通过save选项设置多个保存条件,只要其中任意一个条件被满足,服务器就会执行BGSAVE命令。

save选项设置的默认条件如下所示:

save 900 1
//服务器在900s(即15分钟)之内,对数据库进行了至少1次修改
save 300 10
//服务器在300s(即5分钟)之内,对数据库进行了至少10次修改
save 60 10000
//服务器在60s(即1分钟)之内,对数据库进行了至少10000次修改

默认的配置条件表示,只要满足以上3个条件中的任意1个,BGSAVE命令就会被执行。

2.2 载入RDB文件

首先,我们要明确的是,载入RDB文件的目的是为了在Redis服务器进程重新启动之后还原之前存储在Redis中的数据。

然后,Redis载入RDB文件并没有专门的命令,而是在Redis服务器启动时自动执行的。

而且,Redis服务器启动时是否会载入RDB文件还取决于服务器是否启用了AOF持久化功能,具体判断逻辑为:

只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据。
如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据。

以上判断逻辑如下图所示:
在这里插入图片描述

2.3 服务器状态

创建和载入RDB文件,可能存在的服务器状态有以下3种:

  • 当执行SAVE命令时,Redis服务器会被阻塞,此时客户端发送的所有命令请求都会被阻塞,只有在服务器执行完SAVE命令,重新开始接受命令请求之后,客户端发送的命令请求才会被处理。
  • 当执行BGSAVE命令时,Redis服务器不会被阻塞,Redis服务器仍然可以继续处理客户端发送的命令请求。
  • 服务器在载入RDB文件期间,会一直处于阻塞状态,直到RDB文件载入成功。

3. AOF持久化

AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库数据的
在这里插入图片描述

3.1 AOF持久化的实现

当AOF持久化功能处于打开状态时,Redis服务器在执行完一个写命令之后,会以协议格式(如上面截图中AOF文件里保存写命令的格式)将被执行的写命令追加到服务器状态的AOF缓冲区的末尾,然后Redis服务器会根据配置文件中appendfsync选项的值来决定何时将AOF缓冲区中的内容写入和同步到AOF文件里面。

appendfsync选项有以下3个值:

  • always

    从安全性来说,always是最安全的(丢失数据最少),因为即使出现故障停机,数据库也只会丢失一个事件循环中所产生的命令数据。

    从效率来说,always的效率最慢,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,并且同步AOF文件。

  • everysec

    从安全性来说,everysec模式下,即使出现故障停机,数据库只会丢失一秒钟的命令数据。

    从效率来说,everysec模式足够快,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,并且每隔一秒就要在子线程中对AOF文件进行同步。

  • no

    从安全性来说,no模式下,如果出现故障停机,数据库会丢失上次同步AOF文件之后的所有写命令数据,具有不确定性,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,至于何时对AOF文件进行同步,则由操作系统控制。

从效率来说,no模式和everysec模式的效率差不多。appendfsync选项的默认值是everysec,也推荐使用这个值,因为既保证了效率又保证了安全性。

3.2 载入AOF文件

因为AOF文件包含了重建数据库所需的所有写命令,所以Redis服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原Redis服务器关闭之前的数据。

Redis读取AOF文件并还原数据库的详细步骤如下:

  1. 创建一个不带网络连接的伪客户端
    因为Redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行AOF文件保存的写命令。
    伪客户端执行命令的效果和带网络连接的客户端执行命令的效果完全一样。
  2. 从AOF文件中分析并读取出一条写命令。
  3. 使用伪客户端执行被读取出的写命令。
  4. 一直执行步骤2和步骤3,直到AOF文件中的所有写命令都被执行完毕。

以上步骤如下图所示:
在这里插入图片描述
如果Redis服务器开启了AOF持久化功能,那么Redis服务器在启动时会载入AOF文件

3.3 AOF重写

因为AOF持久化是通过保存被执行的写命令来记录数据库数据的,所以随着Redis服务器运行时间的增加,AOF文件中的内容会越来越多,文件的体积会越来越大,如果不做控制,会有以下2点坏处:

  1. 过多的占用服务器磁盘空间,可能会对Redis服务器甚至整个宿主计算机造成影响。
  2. AOF文件的体积越大,使用AOF文件来进行数据库还原所需的时间就越多。

AOF文件重写功能的实现原理为:

首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令。

3.3.2 AOF后台重写

因为AOF文件重写会进行大量的文件写入操作,所以执行这个操作的线程将被长时间阻塞。

因为Redis服务器使用单个线程来处理命令请求,所以如果由服务器进程直接执行这个操作,那么在重写AOF文件期间,服务器将无法处理客户端发送过来的命令请求。

为了避免上述问题,Redis将AOF文件重写功能放到子进程里执行,这样做有以下2个好处:

  1. 子进程进行AOF文件重写期间,服务器进程(父进程)可以继续处理命令请求。
  2. 子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。

4. RDB持久化、AOF持久化的区别

4.1 实现方式

RDB持久化是通过将某个时间点Redis服务器存储的数据保存到RDB文件中来实现持久化的。

AOF持久化是通过将Redis服务器执行的所有写命令保存到AOF文件中来实现持久化的。

4.2 文件体积

由上述实现方式可知,RDB持久化记录的是结果,AOF持久化记录的是过程,所以AOF持久化生成的AOF文件会有体积越来越大的问题,Redis提供了AOF重写功能来减小AOF文件体积。

4.3 安全性

AOF持久化的安全性要比RDB持久化的安全性高,即如果发生机器故障,AOF持久化要比RDB持久化丢失的数据要少。

因为RDB持久化会丢失上次RDB持久化后写入的数据,而AOF持久化最多丢失1s之内写入的数据(使用默认everysec配置的话)。

4.4 优先级

由于上述的安全性问题,如果Redis服务器开启了AOF持久化功能,Redis服务器在启动时会使用AOF文件来还原数据,如果Redis服务器没有开启AOF持久化功能,Redis服务器在启动时会使用RDB文件来还原数据,所以AOF文件的优先级比RDB文件的优先级高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值