Redis(1)——持久化

目录

一、RDB

[1.1 RDB的触发方式](#1.1 RDB的触发方式)

[1.2 bgsave的流程](#1.2 bgsave的流程)

[1.3 实际执行](#1.3 实际执行)

[1.4 RDB的优缺点](#1.4 RDB的优缺点)

二、AOF

[2.1 开启AOF](#2.1 开启AOF)

[2.2 AOF文件写入](#2.2 AOF文件写入)

[2.3 AOF重写机制](#2.3 AOF重写机制)

[2.4 AOF重写的流程](#2.4 AOF重写的流程)

[2.5 混合持久化](#2.5 混合持久化)

[2.6 数据恢复](#2.6 数据恢复)


Redis的直观的特性就是相比数据库更快,效率更高,这是因为Redis的数据存储在内存上,所以我们可以做到快速读写,但是如果数据值存放到内存上是不持久的,如果主机或进程重启,数据就不存在了。

所以我们Redis的数据既要存储在内存上以此来实现"快",同时也要存储到硬盘上,以此来实现持久化。这样如果Redis重启后也可以从硬盘中读取数据来恢复内存中的数据

那么Redis该如何把数据存储到硬盘上呢,Redis向我们提供了两种策略

RDB:Redis DataBase :定期备份

AOF:Append Only File:实时备份

一、RDB

RDB定期把我们Redis内存中的数据,都写入到硬盘中,生成一个"快照"。可以理解为Redis给内存当前存储的数据赶紧拍个照片生成一个文件,存储到硬盘中,后续如果Redis重启,就可以通过硬盘里的"快照"文件恢复内存的数据

1.1 RDB的触发方式

1. 手动触发

我们可以通过在Redis命令行中输入指定命令来触发快照的生成

  • save :执行save的时候,Redis就会把让所有资源都用来进行"快照生成"操作,此时就会阻塞Redis的其他命令,所以我们一般不建议使用save命令
  • bgsave :bg就是background的意思,所以这个"快照生成"的过程是在背后进行的,不会阻塞Redis,也就不会影响Redis处理别的命令

2. 自动触发

除了在Redis客户端命令行输入指令的方式,我们还可以在Redis的配置文件中进行配置,让Redis在一定时间内自动进行RDB

在etc/redis文件夹中有一个redis.conf配置文件

文件中这里的配置就是对RDB的自动触发配置

3600 1:在3600秒(1小时)至少有1次数据修改

300 100:在300秒(5分钟)至少有100次数据修改

60 10000:在60秒(1分钟)至少有10000次数据修改

如果觉得这个配置不符合我们的业务需求,也可以在这个配置文件中进行修改

同时我们可以在这个配置文件中查看快照文件的位置

我们进入快照文件查看,这个rdb文件是一个二进制文件,内存中的数据以二进制的形式保存到这个文件中,redis重启的时候就会去读取这个文件,从而恢复内存中的数据,如果我们对这个文件进行了修改,redis服务可能就无法启动了

1.2 bgsave的流程

  • 当我们触发bgsave命令时,父进程首先会判断当前是否有其他正在执行的子进程,如果存在bgsave直接返回,不做任何操作
  • 如果没有其他子进程,父进程调用fork(),就会创建一个子进程,这个子进程会拥有父进程的所有信息,可以说父进程和子进程是相同的,子进程的物理内存是通过写时复制机制和父进程共享
    • 写时复制:如果是读操作的命令,子进程仍然和父进程共享内存空间,但是如果客户端输入写操作的命令,父进程就会申请一块新的空间,在这个新的空间进行修改。
    • 比如:父进程有个变量n=10,调用fork(),子进程也会有一个变量n=10,并且和父进程的n变量共享一块内存空间,父进程还要继续相应客户端的命令,如果客户端输入了写操作的命令,修改n=20,此时父进程就会申请一块新空间存储n=20,子进程的n还是等于10,并且跟父进程也不是共享一块空间了
    • 根据结果来说,就是子进程只会拥有fork()调用之前的所有数据。
  • fork()调用之后,子进程遍历当前内存所有的数据,按照RDB文件的格式,将数据写入一个临时文件
  • 写入完成之后,再把这个文件重命名为dump.rdb,替换原来旧的RDB快照文件

1.3 实际执行

先查看dump.rdb详情信息,inode是800816,文件内部的信息如下

我们现在一个客户端上设置三个键值对,此时我们去另一个客户端查看一下快照文件

可以看到dump.rdb的详情信息,他的inode此时是802428,和之前相同,可见并没有把我们直接设置的键值对储存起来,这是因为我们还没有满足自动触发rdb的条件

此时我们手动触发rdb

再去查看一下快照文件的信息,发现inode已经和之前不同了,说明确实进行了快照文件的替换

我们进入文件查看,发现里面确实存储了我们之前设置的键值对

我们再设置一个key4键值对

设置完后我们进入rdb快照文件,里面仍只有三个键值对,并没有我们刚刚设置的key4

此时我们退出客户端,重新启动redis服务,再进入客户端,发现key4竟然还是保存的

我们再进入rdb文件,发现key4保存在文件中了

说明,自动触发rdb快照除了配置redis.conf文件,在重新启动服务器的时候,redis也会自动触发rdb机制,保存快照文件

上述重启redis服务器的方式是正常关闭服务器的方式,我们再试一下非正常关闭服务器

先设置键值对key5

然后进行查看redis服务的进程号

直接使用kill -9命令删除进程,这样属于非正常关闭,我们再进入redis客户端,发现key5并没有存储成功

1.4 RDB的优缺点

优点

  • RDB是一个二进制文件,代表Redis在某个时间点上数据快照,非常适用于备份等场景
  • Redis加载RDB恢复数据远远快于AOF的方式

缺点

  • RDB存储数据没有办法做到实时持久化,上述提到的自动触发RDB也是有时间限制的,满足一段时间内固定次数修改才会触发RDB,那么如果还未触发之前服务器就挂了,这段时间内我们的数据就丢失了
  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个RDB版本,兼容性会有风险

二、AOF

AOF持久化是以独立日志的方式记录每次写命令,AOF文件是文本文件,重启时再重新执行AOF文件的命令达到恢复数据的目的。相比于RDB一段时间记录数据,AOF解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。如果将RDB比作是照片,记录了十点和十一点两张照片,那么AOF就是摄影,拍摄了十点到十一点一个小时的内容,所以保证了实时性

2.1 开启AOF

同样要在redis.conf里配置,这里默认是no未开启,我们把no改成yes,此时就开启AOF

AOF的日志命名是"appendonly.aof",和之前的dump.rdb同样在var/lib/redis文件中

修改完配置后我们要进行重启Redis服务,我们再进入文件夹,就能查看到aof的文件了

我们查看文件,可以按到我们之间的数据被记录在aof

2.2 AOF文件写入

当我们引入AOF之后,Redis又要在内存中写数据,又要把数据写入硬盘里的AOF文件,这样速度不会降低吗?

实际上没有影响,AOF机制并非直接把数据写入硬盘,而是写入内存中的缓冲区aof_buf,积累一段时间后再统一写入硬盘

缓冲区的刷新策略

我们可以在redis.conf文件中配置刷新策略

always频率最高,数据可靠性最高,性能最低

everysec频率中等,数据可靠性会降低,性能会提高

no频率最低,数据可靠性也是最低的,性能是最高(这是依靠操作系统进行刷新缓冲区)

2.3 AOF重写机制

AOF会把每个命令追加到AOF文件中,这样AOF文件就会持续增长,体积越来越大,那么就会影响到redis下次启动读取文件的时间,所以AOF有一个重写机制

已知AOF会记录所有的命令操作,比如

set key 111

set key 222

set key 333

这三条命令其实是冗余的,其实最后结果就是set key 333,所以我们只保留最后一条命令即可,也就是只针对最后的结果,剔除一些冗余的操作,从而达到给aof文件瘦身的效果

手动触发:调⽤ bgrewriteaof 命令。

⾃动触发:根据auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定⾃动触发时机

  • auto-aof-rewrite-min-size:表⽰触发重写时 AOF 的最⼩⽂件⼤⼩,默认为 64MB
  • auto-aof-rewrite-percentage:代表当前 AOF 占⽤⼤⼩相⽐较上次重写时增加的⽐例

2.4 AOF重写的流程

当我们调用bgrewriteaof命令后

父进程就会调用fork(),会创建一个子进程,子进程拥有父进程的数据

在这期间父进程仍然会收到客户端的命令,这些命令会同时写入到aof_buf和aof_rewrite_buf两个缓冲区,aof_buf是上面aof机制的常规缓冲区,aof_buf里缓冲区的数据还是按照everysec策略写入到旧的AOF文件,aof_rewrite_buf是重写时的缓冲区

子进程会在内存中,遍历所有的数据,将数据写入到新创建的AOF文件

子进程写入完成之后,父进程会把aof_rewrite_buf缓冲区里重写时收到的命令再追加到新的AOF文件里

最后用新的AOF文件替换旧的AOF文件

这里最后要用新的AOF文件替换旧的AOF文件,那为什么还要把数据写入旧的AOF文件呢?

因为如果重写的新的AOF文件出现错误,最后并没有成功实现替换,这样重写时父进程收到的命令就会都丢失,所以旧的AOF文件同样得要写入数据,防止数据丢失

2.5 混合持久化

AOF是按照文本的方式来写入文件,这样后续加载的成本是比较高的,所以redis引入了"混合持久化"的方式,结合了rdb和aof的特点

混合持久化就是按照aof的方式,将每个操作记录到aof文件里,触发aof重写之后,就会把内存状态按照rdb的二进制格式写入到新的aof文件,后续的操作仍然是按照aof文本的方式追加到文件中

2.6 数据恢复

RDB和AOF都开启的时候,是读取RDB文件还是AOF文件呢?

Redis首选AOF文件,如果AOF文件存在就加载这个文件,加载成功就启动成功,如果AOF文件不存在就去加载RDB文件,这是因为AOF文件是实时性备份,数据比RDB更加全,所以首选AOF

相关推荐
君子剑mango2 小时前
MySQL8.0 窗口函数
数据库·mysql
VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue乡村振兴服务系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
大柏怎么被偷了2 小时前
【Linux】文件系统
linux·运维·数据库
即将进化成人机2 小时前
验证码生成 + Redis 暂存 + JWT 认证
数据库·redis·笔记
画***林2 小时前
雷家林诗歌集录一英文版Collected Poems of Lei Jialin, Volume I (English Edition)
数据库·sql
fantasy_arch3 小时前
pd_process.c 文件源码分析
c语言·数据库·视频编解码·av1
Elastic 中国社区官方博客3 小时前
Kibana:使用 ES|QL 构建地图,对国家或地区的指标进行对比
大数据·数据库·elasticsearch·搜索引擎·信息可视化·全文检索·kibana
vortex53 小时前
ORM是什么?如何理解ORM?ORM的优缺点?
java·数据库·sql·mysql·oracle·orm
盟接之桥3 小时前
盟接之桥--说制造:从“找缝隙”到“一万米深”——庖丁解牛式的制造业精进之道
大数据·前端·数据库·人工智能·物联网·制造