Redis|Redis——详解持久化


哈喽!大家好,我是【一心同学】,一位上进心十足的【Java领域博主】!
?【一心同学】的写作风格:喜欢用【通俗易懂】的文笔去讲解每一个知识点,而不喜欢用【高大上】的官方陈述。

?【一心同学】博客的领域是【面向后端技术】的学习,未来会持续更新更多的【后端技术】以及【学习心得】。

?如果有对【后端技术】感兴趣的【小可爱】,欢迎关注【一心同学】

??????感谢各位大可爱小可爱!??????
目录
前言
一、持久化方式
二、RDB机制
2.1 介绍
2.2 触发机制
save触发方式
bgsave触发方式
自动触发
2.3 RDB优缺点
优点
缺点
三、AOF机制
3.1 介绍
3.2 AOF的配置
3.3 AOF触发机制
3.4 重写机制
问题引入
重写原理
重写触发机制
3.5 AOF的优缺点
优点
缺点
四、RDB与AOF的混合持久化
小结
前言
我们的Redis是属于内存数据库,所以将数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。

一、持久化方式
在Redis中提供了两种持久化方式:
方式一:RDB持久化
原理:将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化。

方式二:AOF(append only file)持久化
原理:将Reids的操作日志以追加的方式写入文件。


二、RDB机制
2.1 介绍
RDB就是将数据以全量备份的快照的形式保存在磁盘(快照我们可以将其理解成当前时刻的数据拍成一张照片保存下来),而且会在指定的时间间隔内将内存中的数据集快照写入磁盘。
这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

操作过程:
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件覆盖上次持久化好的文件。整个过程中,主进程是 不进行任何IO操作的。

Redis|Redis——详解持久化
文章图片



2.2 触发机制
由于RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么也就是说会有触发机制,RDB提供了三种触发机制:
  • save
  • bgsave
  • 自动化

save触发方式

命令:
127.0.0.1:6379> save OK


这种方式会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止,执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。具体流程如下:

Redis|Redis——详解持久化
文章图片



注意:我们的客户端可能都是几万或者是几十万,这种方式显然不可取。

bgsave触发方式

命令:
127.0.0.1:6379> bgsave Background saving started


执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:
Redis|Redis——详解持久化
文章图片


具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。bgsave命令也是Redis内部RDB操作的默认方式。

save与bgsave对比:

Redis|Redis——详解持久化
文章图片



自动触发

自动触发,需要我们用配置文件redis.conf配置进行完成,默认采用的是bgsave方式,我们可以对其进行如下配置:

1、save
用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。

当在规定的时间内,Redis发生了写操作的个数满足条件,会触发发生BGSAVE命令。
save

例如:save 300 10 表示的是300 秒内如果至少有 10 个 key 的值变化,则保存。


如果用户设置了多个save的选项配置,只要其中任一条满足,Redis都会触发一次BGSAVE操作

save 900 1 save 300 10 save 60 10000

以上配置的含义:
900秒之内至少一次写操作、
300秒之内至少发生10次写操作、
60秒之内发生至少10000次写操作
只要满足任一条件,均会触发bgsave

注意:不需要持久化的话,可以注释掉所有的 save 行来停用保存功能。

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

3、rdbcompression
默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。

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

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

6、dir
设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名

我们可以修改这些配置来实现我们想要的效果。

2.3 RDB优缺点
优点
(1)RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
(2)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
(3)性能最大化。持久化时唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。

缺点
RDB快照是一次全量备份,无法做到实时持久化,若在两次bgsave间宕机,则会丢失区间(分钟级)的增量数据,不适用于实时性要求较高的场景


三、AOF机制
3.1 介绍
AOF日志是持续增量的备份,是基于写命令存储的可读的文本文件。AOF日志会在持续运行中持续增大,由于Redis重启过程需要优先加载AOF日志进行指令重放以恢复数据,恢复时间会无比漫长。所以需要定期进行AOF重写,对AOF日志进行瘦身。目前AOF是Redis持久化的主流方式。


AOF工作机制很简单,Redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。

Redis|Redis——详解持久化
文章图片



3.2 AOF的配置
AOF默认是关闭的,我们可以通过redis.conf配置文件进行开启。
以下是AOF中常见的配置以及说明:
## 此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能 ## 只有在“yes”下,aof重写/文件同步等特性才会生效 appendonly yes## 指定aof文件名称 appendfilename appendonly.aof## 指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec appendfsync everysec## 在aof-rewrite期间,appendfsync是否暂缓文件同步,"no"表示“不暂缓”,“yes”表示“暂缓”,默认为“no” no-appendfsync-on-rewrite no## aof文件rewrite触发的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才会触发rewrite,默认“64mb”,建议“512mb” auto-aof-rewrite-min-size 64mb## 相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比 ## 每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A) ## aof文件增长到A*(1 + p)之后,触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。 auto-aof-rewrite-percentage 100


3.3 AOF触发机制
Redis提供了三种AOF触发机制,可在redis.conf配置文件中的属性appendfsync上进行配置。
  • always:每一条AOF记录都立即同步到文件,性能很低,但较为安全。
  • everysec:每秒同步一次,性能和安全都比较中庸的方式,也是redis推荐的方式。如果遇到物理服务器故障,可能导致最多1秒的AOF记录丢失。
  • no:Redis永不直接调用文件同步,而是让操作系统来决定何时同步磁盘。性能较好,但很不安全。
Redis|Redis——详解持久化
文章图片



3.4 重写机制
问题引入
持久化文件会随着写指令的增加而变得越来越大。
例如调用incr num100次,文件中保存了100条指令,其实99条是多余的,因为要恢复数据库的状态只需执行一条set num 100就够了。为了压缩AOF持久化文件,Redis提供了AOF的重写机制。

重写的目的:
用来一定程度上减小AOF文件的体积。

重写原理
重写AOF时,并没有读取旧的AOF文件,而是将内存中的数据用命令的方式重写了一个新的AOF文件替换旧的AOF文件。

重写流程:
(1)Redis调用fork,子进程根据内存中的数据快照,往临时文件中写入重建数据库状态的命令。
(2)父进程继续处理客户端请求,除了将写命令追加到原来的文件中,同时将其缓存起来。这样可以保证子进程如果重写失败不会出现问题。
(3)当子进程写入完成后通知父进程,父进程就将缓存中的命令写入到临时文件中。
(4)父进程将临时文件替换旧的AOF文件并重命名,后续的命令追加到新的AOF文件中。

Redis|Redis——详解持久化
文章图片




重写触发机制

AOF触发机制与RDB类似,也分为:手动触发和自动触发

手动触发:
直接调用bgrewriteaof命令
redis-cli -h ip -p port bgrewriteaof


自动触发
根据redis.conf配置文件中的auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。
auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB(我们线上是512MB)。auto-aof-rewrite-percentage:代表当前AOF文件空间(aof_current_size)和上一次重写后AOF文件空间(aof_base_size)的值



3.5 AOF的优缺点
优点
(1)AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。
(2)AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。
(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
(4)AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据

缺点
(1)AOF方式生成的日志文件太大,需要不断AOF重写,进行瘦身,即使经过AOF重写瘦身,由于文件是文本文件,文件体积还是较大(相比于RDB的二进制文件)。
(3)AOF重演命令式的恢复数据,速度显然比RDB要慢。


四、RDB与AOF的混合持久化
对于RDB与AOF之间的对比如下:
Redis|Redis——详解持久化
文章图片

通过上面对RDB和AOF的描述,我们可以发现以下问题:
  • 仅使用RDB快照方式恢复数据,由于快照时间粒度较大,时回丢失大量数据。
  • 仅使用AOF重放方式恢复数据,日志性能相对 rdb 来说要慢。在 Redis 实例很大的情况下,启动需要花费很长的时间。

Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。

介绍:
将 RDB 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。相当于:
  • 大量数据使用粗粒度(时间上)的rdb快照方式,性能高,恢复时间快。
  • 增量数据使用细粒度(时间上)的AOF日志方式,尽量保证数据的不丢失。

工作流程:
在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。


小结

以上就是【一心同学】看了网上不少【技术文章】所整理出来的【Redis的持久化】讲解,Redis的两种持久化方式既可以【Redis的持久化】,也可以【同时使用】,也可以都不使用。我们根据在不同的场景进行选择不同的持久化方式,【没有最好,只有最合适】。


【Redis|Redis——详解持久化】如果这篇【文章】有帮助到你,希望可以给【一心同学】点个赞,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【后端技术】感兴趣的小可爱,也欢迎关注?????? 【一心同学】??????,我将会给你带来巨大的【收获与惊喜】!

    推荐阅读