0


Redis——详解持久化

📢📢📢📣📣📣

哈喽!大家好,我是【一心同学】,一位上进心十足的【Java领域博主】!😜😜😜

✨【一心同学】的写作风格:喜欢用【通俗易懂】的文笔去讲解每一个知识点,而不喜欢用【高大上】的官方陈述。

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

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

❤️❤️❤️感谢各位大可爱小可爱!❤️❤️❤️


前言

我们的Redis是属于内存数据库,所以将数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。

一、持久化方式

在Redis中提供了两种持久化方式:

🚀 方式一:RDB持久化

原理将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化。

🚀 方式二AOF(append only file)持久化

原理将Reids的操作日志以追加的方式写入文件。

二、RDB机制

2.1 介绍

RDB就是将数据以全量备份的快照的形式保存在磁盘(快照我们可以将其理解成当前时刻的数据拍成一张照片保存下来),而且会在指定的时间间隔内将内存中的数据集快照写入磁盘。

这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

🚀 操作过程****:

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

2.2 触发机制

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

  • save
  • bgsave
  • 自动化

🌴 save触发方式

** 命令:**

127.0.0.1:6379> save
OK

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

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

🌴 bgsave触发方式

命令:

127.0.0.1:6379> bgsave
Background saving started

执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:

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

🔥 save与bgsave对比:

🌴 自动触发

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

1、save

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

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

例如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函数追加到文件中。通俗的理解就是日志记录。

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永不直接调用文件同步,而是让操作系统来决定何时同步磁盘。性能较好,但很不安全。

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文件中。

🌴 重写触发机制

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

🚀 手动触发:

直接调用bgrewriteaof命令

redis-cli -h ip -p port bgrewriteaof

🚀 自动触发

根据redis.conf配置文件中的auto-aof-rewrite-min-sizeauto-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之间的对比如下:**

通过上面对RDB和AOF的描述,我们可以发现以下问题:

  • 仅使用RDB快照方式恢复数据,由于快照时间粒度较大,时回丢失大量数据。
  • 仅使用AOF重放方式恢复数据,日志性能相对 rdb 来说要慢。在 Redis 实例很大的情况下,启动需要花费很长的时间。

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

🌵 介绍:

将 RDB 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。相当于:

  • 大量数据使用粗粒度(时间上)的rdb快照方式,性能高,恢复时间快。
  • 增量数据使用细粒度(时间上)的AOF日志方式,尽量保证数据的不丢失。

🌵 工作流程:

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


小结

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

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

标签: redis 缓存 rdb

本文转载自: https://blog.csdn.net/Huang_ZX_259/article/details/122805306
版权归原作者 一心同学 所有, 如有侵权,请联系我们删除。

“Redis&mdash;&mdash;详解持久化”的评论:

还没有评论