Hey, Nice to meet You. 

必有过人之节.人情有所不能忍者,匹夫见辱,拔剑而起,挺身而斗,此不足为勇也,天下有大勇者,猝然临之而不惊,无故加之而不怒.此其所挟持者甚大,而其志甚远也.          ☆☆☆所谓豪杰之士,

Redis持久化之RDB

1、Redis持久化介绍

我们都知道Redis所有的数据都存在内存中,这与传统的MySQL,Oracle等关系型数据库直接将内容保存到硬盘中相比,内存数据库的读写效率比传统数据库要快的多(内存的读写效率远远大于硬盘的读写效率)。但是保存在内存中也随之带来了一个缺点,一旦断电或者宕机,那么内存数据库中的数据将会全部丢失。

为了解决这个缺点,Redis提供了将内存数据持久化到硬盘,以及用持久化文件来恢复数据库数据的功能,从内存当中同步到硬盘上,这个过程叫做持久化过程。

Redis 支持两种形式的持久化,一种是RDB快照(snapshotting),另外一种是AOF(append-only-file),配置可以禁用持久化功能,也可以同时使用两种方式,这里先对 RDB 进行介绍。

  • rdb方式:Redis默认的持久化方式。在指定的时间间隔内写入硬盘,压缩为一个二进制的文件(dump.rdb)。
  • aof方式:以日志的形式记录每一个写操作(读操作不记录),服务器启动后就构建数据库。

2、RDB持久化介绍

RDB全称Redis Database,RDB持久化就是把当前Redis数据库中的内存数据保存到硬盘的过程,RDB方式是Redis默认支持的。

它的触发时机:RDB持久化的触发方式有两种,

  1. 自动触发
  2. 手动触发

先来看看RDB触发条件:

  • 符合自定义配置的快照规则
  • 执行save或者bgsave命令
  • 执行flushall命令
  • 执行主从复制操作

3、自动触发

我们通过查看 redis.conf 配置文件里面的 SNAPSHOTTING 内容可知:

image

这个 SNAPSHOTTING 快照部分可以配置的属性非常多,我们来详细介绍一下:

①、save:这是默认触发Redis的RDB持久化的条件,如果你只是用Redis的缓存功能,不需要持久化,那么你可以注释掉所有save的默认配置来停用保存功能。可以直接一个空字符串来实现停用:save " "。默认配置:

save 900 1:    表示900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10:   表示300 秒内如果至少有 10 个 key 的值变化,则保存
save 60  10000:表示60  秒内如果至少有 10000 个 key 的值变化,则保存

②、stop-writes-on-bgsave-error :默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了

③、rdbcompression ;默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。

④、rdbchecksum :默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

⑤、dbfilename :设置快照的文件名,默认是 dump.rdb

⑥、dir:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。默认是和当前配置文件保存在同一目录。

4、手动触发

通过命令save或者是bgsave(一般不会直接用命令生成RDB文件)

  1. save:此命令会使用Redis的主线程进程同步存储,阻塞当前的Redis服务器,造成服务不可用,直到RDB过程完成。无论当前服务器数据量大小,线上不要用
  2. bgsave:此命令会通过fork()创建子进程,在后台进程存储。只有fork阶段会阻塞当前Redis服务器,不必到整个RDB过程结束,一般时间很短。因此Redis内部涉及到RDB都采用bgsave命令。这里注意一点,无论RDB还是AOF,由于使用了写时复制,fork出来的子进程不需要拷贝父进程的物理内存空间但是会复制父进程的空间内存页表。

5、RDB运行原理(fork() + copyonwrite)

当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

image

  1. Redis执行bgsave命令,Redis判断当前存在正在进行执行的子进程,如RDB/AOF子进程,存在bgsave命令直接返回
  2. 不存在则使用fork函数复制一份当前进程的副本(子进程),子进程与Redis主进程共享同一份内存空间,所以子进程可以搞他的rdb文件持久化工作,主进程又能继续他的对外提供服务,二者互不影响。
  3. 父进程继续接受并处理客户端发来的命令,
  4. 子进程开始将内存中的数据写入到硬盘中的临时文件。当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
  5. 子进程告诉父进程处理完成,至此,一次快照操作完成

想搞懂RDB原理的可以参考这篇博客彻底搞懂Redis持久化之RDB原理 写的非常详细,值得详细。

6、RDB优缺点

--优点

  • RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份
  • 只有一个文件,保存时间间隔的数据,方便压缩转移(就一个文件)
  • 因为RDB是利用fork下面的子进程来进行持久化,所有Redis加载RBD恢复数据会比使用AOF恢复数据快

--缺点

  • 没办法做到实时准实时的持久化,如果出现断电或者宕机,可能导致最后面部分数据丢失。
  • RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒。

7、恢复数据

将备份文件 (dump.rdb) 移动到 Redis 安装目录并启动服务即可,Redis就会自动加载文件数据至内存了。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。

8、停止 RDB 持久化

有些情况下,我们只想利用Redis的缓存功能,并不像使用 Redis 的持久化功能,那么这时候我们最好停掉 RDB 持久化。可以通过上面讲的在配置文件 redis.conf 中,可以注释掉所有的 save 行来停用保存功能或者直接一个空字符串来实现停用:save ""

也可以通过命令:

redis-cli config set save " "

注意:如果执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义。

posted @ 2021-02-01 15:04  唐浩荣  阅读(511)  评论(0编辑  收藏  举报