Redis:持久化之RDB

Redis高性能的背后很大程度上是因为其将所有数据都存储在内存,然而当Redis重启后,所有存储在内存中的数据就会丢失。

这时我们希望Redis能将数据从内存中以某种形式同步到磁盘中,使得重启后可以根据磁盘中的记录恢复数据,这一过程称之为持久化。

Redis支持两种方式的持久化:一种是RDB方式,另一种是AOF方式。前者根据指定的规则“定时”将内存中的数据存储在磁盘上,而后者在每次执行命令后将命令本身记录下来。

两种持久化方式可以单独使用其中一种,但更多场景下都是将两者一起使用。今天先说说RDB这种持久化方式。

1. RDB简介

RDB方式的持久化是通过快照完成的,当符合一定条件时Redis会自动将内存中的所有数据生成一份副本并存储在磁盘上,这个过程即为“快照”。

2. 触发方式

触发Redis进行快照主要有两种方式,分别是自动触发和手动触发。

2.1 自动触发

自动触发是指当满足符合规则条件时,Redis服务自动进行快照。自动触发的条件由redis.conf配置文件的以下配置决定:

在这里插入图片描述

save m n表示m秒内数据集存在n次修改时,自动触发bgsave。

2.2 手动触发

手动触发Redis进行RDB持久化的命令有两种:

(1)save:执行该命令时 ,Redis服务器会被阻塞,不能再接收和处理其它命令,直到整个RBD持久化过程结束为止。

(2)bgsave:执行该命令时,Redis会在后台异步进行快照,此时Redis仍可对外响应来自客户端的请求。实际上Redis的大部分RDB操作都是基于bgsave命令。

3. 相关配置

除了上面自动触发的save m n的配置,在redis.conf配置文件中还有其它一些跟RDB相关的配置。主要有以下几个:

(1)stop-writes-on-bgsave-error:默认值为yes。当启用了RDB并且最后一次保存数据失败时,Redis是否停止写入数据。

(2)rdbcompression:默认值是yes。用于表示持久化时,写入磁盘的快照文件是否需要压缩处理。

(3)rdbchecksum:默认值是yes。在存储快照后,我们还可以让redis进行数据校验,但这样做会增加更多的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

(4)dbfilename:设置快照的文件名,默认是dump.rdb

(5)dir:设置快照文件的存放路径。

4. 恢复数据

接下来我们通过手动触发快照的方式来演示RDB持久化的过程。

场景一:在redis中保存几条数据,立即停掉redis进程,然后重启redis,看看刚才插入的数据还在不在。

(1)首先我们进入redis的dir配置对应的路径,可以看到此时该目录下还没有rdb文件。

在这里插入图片描述

(2)进入redis cli交互命令行,并设置一个键值对,然后立即停掉redis进程。

在这里插入图片描述

(3)重启redis服务,看看刚刚的键值对是否被持久化。

在这里插入图片描述

可以看到k1的值还在,为什么?理论上来说,我们在设置了k1的值后是立即停掉redis进程的,还没到snapshotting检查点,但是我们可以看到在dir配置的目录下,确实生成了一个dump.rdb文件。

在这里插入图片描述

其实,在这里我们通过redis-cli SHUTDOWN方式去停掉redis进程,这是一种安全退出的模式,redis在退出的时候会将内存中的数据立即生成一份完整的rdb快照。请看场景二的演示。

场景二:在redis中再保存几条新的数据,立即用kill -9粗暴杀死redis进程,模拟redis故障异常退出,导致内存数据丢失的场景。

(1)此时dump.rdb中有一个k1键值对,我们现在增加一个k2键值对,然后通过kill -9命令直接杀死进程。

在这里插入图片描述

(2)重启redis服务, 看看刚刚的k2是否被持久化。可以看到k2的值没有被持久化,由于k1已经在dump.rdb中被持久化,所以k1的值仍然在。

在这里插入图片描述

场景三:手动设置一个save检查点,然后通过kill -9粗暴杀死redis进程,模拟redis故障异常退出。

(1)我们设置一个检查点,每5s有一个值发生变更,就生成一个新的dump.rdb文件。

save 900 1
save 300 10
save 60 10000
save 5 1

(2)删除已经存在dump.rdb文件,并重启redis。

在这里插入图片描述

(3)设置k1的值,然后过5s后,通过kill -9杀死进程。

在这里插入图片描述

(4)重启redis服务, 看看刚刚的k1是否被持久化。可以看到k1的值在5s后被持久化,即使通过kill -9暴力停止redis服务,仍然被写入dump.rdb中。

在这里插入图片描述

5. 停止RDB持久化

如果我们只想将Redis作为缓存系统使用,并不需要考虑数据的持久化,那么我们如何关闭RDB持久化呢?很简单,只需要将redis.conf配置文件的所有save行注释掉即可。

6. 快照原理

Redis默认会将快照文件存储在Redis当前进程的工作目录的dump.rdb文件中,当然我们也可以通过配置dir和dbfilename两个参数分别指定快照文件的存储路径和文件名。其快照的过程如下:

(1)Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);

(2)父进程继续接收并处理客户端请求,而子进程开始讲内存中的数据写入磁盘中的临时文件;

(3)当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照操作完成。

整个快照过程中Redis不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说RDB文件在任何时候都是完整的,这使得我们可以通过定时备份RDB文件来实现Redis数据库的备份。

通过RDB方式实现持久化,一旦Redis发送异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要根据实际使用场景通过组合设置自动快照条件的方式来将可能发生的数据损失控制在可接受范围内。如果无法忍受近几秒或者更长的数据丢失,则可以考虑使用AOF方式进行持久化。

——End——
更多精彩分享,可扫码关注微信公众号哦。

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章