当前位置: 首页 > news >正文

【Redis学习】持久化机制(RDB/AOF)

Redis学习:

https://blog.csdn.net/2301_80220607/category_13051025.html?spm=1001.2014.3001.5482

1. 认识持久化

学习过mysql的都知道,mysql事务有四个非常重要的特性:原子性、一致性、持久性、隔离性。这里的持久性就是我们这里要说的持久化了,那么MySQL是如何做到数据的持久性的呢?方法就是将数据存储到磁盘中去,那么redis能否这样做呢?

我们前面一直在说,Redis之所以能够做到快速的对数据进行操作,原因就是它是将数据存储在内存中的,如果我们将数据存储到磁盘上,那么Redis不就会丧失它的特性了嘛。但并不意味着我们的Redis就无法进行持久化操作了,我们采取的方法是:在内存和磁盘上各存储一份。

磁盘上的那份只负责:当我们打开Redis时,对我们之前的数据进行恢复;平时的使用还是直接在内存中进行。这样的缺点就是消耗的空间变多了,因为我们相当于要写入两份数据(内存和磁盘),但总体来说还是问题不大的,因为磁盘价格很低

Redis支持RDB (Redis DateBase) 和AOF (Append Only File) 两种持久化机制,具体到方法上来说就是支持定期备份和实时备份两种方法。

2. RDB机制

RDB机制就是按照定期备份的方法来对我们的数据进行持久化的。Redis定期的把内存中的数据全部写入磁盘中,生成一个快照,后续重启Redis的时候,虽然我们内存中的数据已经没了,但是我们可以通过磁盘中的快照文件恢复原来的数据

2.1 触发机制

定期备份的触发方式有两种:手动触发和自动触发

手动触发分别对应save和bgsave命令

  • save命令:阻塞当前进程,直到RDB过程完成为止,对于内存比较大的实例是比较灾难的,因为Redis是单线程的,所以我们一般不使用这个命令
  • bgsave命令:Redis进程执行fork创建子进程,子进程来完成Redis的持久化工作,完成后自动结束。这种方法阻塞只发生在fork阶段,时间比较短

除了手动触发外,Redis运行自动触发Redis备份机制,这种机制在实战中更有意义

  • 使用save配置:如“save m n”表示m秒内,数据集发生了n次修改,就自动RDB持久化
  • 从节点进行全量复制操作时,主节点自动进行RDB持久化,随后将RDB文件内容发送给从节点
  • 执行shutdown命令关闭Redis时,执行RDB持久化

2.2 bgsave命令的流程说明

  1. 执行bgsave命令,Redis判断现在是否有正在执行的子进程,比如RDB/AOF子进程,如果有,bgsave直接退出
  2. ⽗进程执⾏ fork 创建⼦进程,fork 过程中⽗进程会阻塞,通过 info stats 命令查看
    latest_fork_usec 选项,可以获取最近⼀次 fork 操作的耗时,单位为微秒。
  3. ⽗进程 fork 完成后,bgsave 命令返回 "Background saving started" 信息并不再阻塞⽗进程,可以继续响应其他命令。
  4. ⼦进程创建 RDB ⽂件,根据⽗进程内存⽣成临时快照⽂件,完成后对原有⽂件进⾏原⼦替换。执 ⾏ lastsave 命令可以获取最后⼀次⽣成 RDB 的时间,对应 info 统计的 rdb_last_save_time 选 项。
  5. 进程发送信号给⽗进程表⽰完成,⽗进程更新统计信息。

3. RDB文件

查看:

首先我们先来看一下我们如何找到RDB文件并进行查看,我们可以先看一下我们Redis的配置文件redis.conf,在/etc/redis这个目录下

我们使用vim进入这个配置文件后,可以查看我们的工作目录为/var/lib/redis

我们的RDB文件就存在于这个工作目录之下:

这个文件我们可以使用vim进行查看,但里面由于是二进制压缩过的,所以我们可以看到里面是乱码。

切记不要手动修改dump.rdb文件中的内容,修改了可能会导致我们的redis无法正确启动

检验:

如果你不小心对dump.rdb文件中的内容做出了修改,或者由于某些原因Redis加载dump.rdb文件时失败了而拒绝启动。这时可以使用Redis提供的redis-check-dump工具检测RDB文件并获取对应的检测报告


我们的Redis是按照一定的规则定期生成RDB文件的,那么具体的生成规则是什么呢?

当执行生成RDB镜像时,我们把要写的快照信息先写入一个临时文件,当这个快照生成完毕之后,我们把原来的RDB文件删除,然后将这个临时文件改名为dump.rdb,所以说RDB文件自始至终只能有一个

4. RDB效果演示

4.1 手动触发

我们同时打开多个终端,一个打开redis进行操作,另一个可以查看dump.rdb文件观察数据的持久化情况

我们可以看到此时我们的redis中是没有数据的,如果此时我们向我们的redis中插入几个值,我们的dump.rdb文件会有变化吗?

插入后我们会发现我们的RDB文件中的内容并没有发生变化,原因是什么呢?其实就是我们前面所说的,RDB机制并不是实时备份的,需要我们手动触发或者满足一定的条件后自动触发

手动触发的方式我们上面讲了是有save和bgsave两种命令:

下面我们看一下具体如何操作

如图我们又添加了两个新的值key3和key4,然后我们使用bgsave手动触发RDB机制,然后此时查看我们的RDB文件,通过一些关键字我们就可以看到我们的值已经被备份到RDB文件中了,此时如果我们重启了redis服务器,RDB文件就会被加载恢复内存之前的状态

在手动触发查看RDB文件时,有一个需要注意的小细节是:这里我们新写入的数据很少,所以手动触发后直接查看RDB文件就可以发现新写的数据已经进行了备份,但是如果我们写入的数据很多,此时再使用bgsave手动触发的时候,子进程就需要更多的时间在后台完成备份,此时我们短时间内就去查看我们的RDB文件可能就会因为还没备份完而看不到新写入的数据

这里我们再讲解一下save和bgsave的区别:

我们上面提到save和bgsave最大的不同就是一个是阻塞当前进程进行备份的,一个是创建子进程进行备份的,那么具体是如何工作的呢?我们可以结合实例看一下

由于我们数据过少的原因,bgsave创建子进程后,子进程的持久化过程是非常快的,所以我们很难通过观察进程的方式来看我们是否创建了一个子进程,但是我们上面还提到的一个东西就是:子进程会将生成的快照先写入一个临时文件中,全部备份完之后会将原RDB文件删除,然后将新生成的文件改名成dump.rdb,所以我们可以通过观察RDB文件inode的方法,来查看bgsave之后是否生成了新的文件,从而来判断我们bgsave是否手动触发成功(save命令是阻塞当前进程,然后将快照直接写入原RDB文件中的,不会生成新的RDB文件)

我们可以使用stat filename命令查看文件的inode

起初RDB文件的inode:

bgsave命令执行后:

我们可以发现RDB文件的inode发生了变化,也就是说这个RDB文件并不是原来的RDB文件了,这就侧面说明我们的bgsave正确完成了备份工作(临时文件+重命名机制)

4.2 自动触发

RDB机制也可以自动触发

我们先来看这样一个现象,当我们往Redis中写入几个值的时候,此时我们如果直接退出Redis(注意要使用ctrl+c,不要使用quit),我们会发现我们刚刚写入的值并没有成功备份,但是如果此时我们重启Redis服务器后(systemctl restat redis-server),再查看dump.rdb文件就会发现已经备份了

这就可以验证我们上面所说的一种自动触发的情况:执行shutdown命令关闭Redis时,执行RDB持久化(正确关闭重启Redis服务器时,也会自动触发)

但是如果我们不是正确退出服务器,而是异常重启(kill -9 或者 服务器断电),此时Redis服务器就会来不及生成 rdb,内存中尚未保存到快照中的数据,就会随着服务器的重启而丢失

如图1,我们 ctrl+c 退出redis后,然后杀死redis服务器,我们会发现redis服务器很快就会自动重启,这是因为Redis是作为系统服务安装的,它被配置为系统服务,由系统的进程管理器(如systemd 或 init)监控和管理。当Redis进程异常退出时,进程管理器会自动重启它。

按照我们上面讲的,异常退出后我们之前插入的数据并没有生成快照保存到RDB文件中,从图二也可以看出我们的RDB文件中并没有 key1 key2,那么为什么我们的redis进程自动重启后,我们进入查看仍能看到之前的数据呢?这实际上是另一种持久化机制---AOF 在发力,下面会讲解


除了这种自动触发方式外,我们上面还提到有两种触发方式:从节点全量复制的时候和满足配置文件配置选项的时候

从节点全量复制也属于一个比较大的话题,后面会讲,现在我们来看一下配置文件这种情况

我们可以查看redis的配置文件(路径:/etc/redis/redis.conf)

里面有这几项内容,最上面的注释语句就是告诉我们 save 配置的规则是:save m n,意思是在m秒内修改n次就会自动触发RDB,最下面的三条就是我们的默认的 save 配置,save " " 的意思是不启用 save 配置(关闭自动生成快照)

4.3 RDB文件的检测

在上面的时候我们就讲到,当我们的 rdb 文件发生损坏的时候,我们的 redis 服务器可能就会无法正常启动,下面我们来故意修改一下 rdb 文件来看一下具体会出什么错误,以及我们如何检测我们出现的错误

我们手动的删除 rdb 文件中间的一些内容,然后再重新启动一下服务器(注意要用 kill -9 的方式启动服务器,因为如果我们使用 systemctl restart redis-server ,会自动触发RDB,然后生成新的RDB 文件)

(注意上面的操作是在关闭了aof机制下进行的,aof机制不关闭的话可能无法观察到这种情况

此时 redis 服务器无法工作的时候,我们可以看看 redis 日志,了解一下发生了什么

redis 日志文件所在的路径为:/var/log/redis(这个路径也是在配置文件中配置的)

我们的RDB文件的修改是在最近一次操作的,所以直接查看最后一条日志就是了,这条日志就告诉我们在 rdb 数据恢复中出现了错误

除了查看日志外,我们也可以通过 redis 提供的检测工具来检查我们的 RDB 文件是否有错误

我们使用这个检测工具也非常简单,在这个命令后加上文件名即可

注意要在RDB文件的工作目录下执行这个检测语句才行,执行后我们也可以看到我们的 RDB 文件是有错误的

观看到之后修复 RDB 文件也很简单,正确重启一次即可(systemctl restart redis-server)

5. RDB机制总结

  • RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照。非常适用于备份,全量复制等场景,比如每6个小时执行bgsave备份,并把 RDB 文件复制到远程机器或者文件系统中(如 hdfs)用于灾备。
  • Redis 加载 RDB 恢复数据远远快于 AOF 的方式,原因:RDB 使用的二进制的方式来组织数据,直接把数据读取到内存中,按照字节的格式取出来,放到结构体/对象中即可;而 AOF 是使用文本的方式来组织数据的,需要进行一系列的字符串切分操作。
  • RDB 方式数据没办法做到实时持久化/秒级持久化。因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高。
  • RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容可能有风险。老版本的 redis 的 RDB 文件放到新版本的 redis 中不一定能识别,如果遇到要升级版本,且遇到了不兼容的问题,可以通过写一个程序的方式,直接遍历旧的 redis 中的所有key,把数据取出来之后,插入到新的 redis 服务器中即可。

http://www.dtcms.com/a/494817.html

相关文章:

  • 栈式自编码器(Stacked Auto-Encoder)
  • 像wordpress一样的网站建设银行网站转账必须u盾吗
  • 让低端机也能飞:Canvas/WebGL/Viz 分层、降级渲染与数据抽样策略
  • 【grafana查询超时问题】
  • 广播系统配线-批量测量快速计算
  • 电商网站商品页的优化目标是什么?第一推是谁做的网站
  • 从零开始的C++学习生活 9:stack_queue的入门使用和模板进阶
  • docker 运行容器限制内存、限制磁盘 IO
  • Compose Multiplatform+Kotlin Multiplatfrom 第七弹跨平台 AI开源
  • C++设计模式_行为型模式_状态模式State
  • 网站怎么绑定域名wordpress zhong
  • wpf中Grid的MouseDown 事件无法触发的原因
  • WPF中的坐标转换
  • 重庆学校网站建设html入门网页制作
  • 词向量:开启自然语言处理的奇妙之旅
  • MySQL 5.7 和 8.0 基于kubernetes的yaml部署方案-单实例和高可用
  • 如何给Windows云主机进行加固
  • binLog、redoLog和undoLog的区别
  • 如何做医美机构网站观察分析电商素材网站
  • k8s localpath csi原理
  • 如何解决在xml中传入Integer整型参数为0时条件失效问题?
  • wordpress建什么站希音跨境电商
  • python爬虫学习
  • MySQL 8.0.29 及以上版本中 SSL/TLS 会话复用(Session Reuse)
  • 【项目-】Qt + QCustomPlot 实现频谱监测仪:四图联动、高频信号注入、鼠标交互全解析
  • 用于博客美化的测试(后面再更新)
  • 【一文了解】正则表达式
  • MySQL中表操作
  • 中国建设银行大学助学贷款网站网站备案对网站负责人的要求
  • 江门云建站模板东城企业网站开发