【redis-02】深入理解redis中RBD和AOF的持久化

news2024/9/23 5:36:31

redis系列整体栏目


内容链接地址
【一】redis基本数据类型和使用场景https://zhenghuisheng.blog.csdn.net/article/details/142406325
【二】redis的持久化机制和原理https://zhenghuisheng.blog.csdn.net/article/details/142441756

如需转载,请输入:https://blog.csdn.net/zhenghuishengq/article/details/142441756

redis的持久化机制和原理

  • 一,redis的持久化机制和原理
    • 1,RDB持久化
      • 1.1,save方式实现
      • 1.2,bgsave的实现
      • 1.3,rdb的优缺点
    • 2,AOF持久化
      • 2.1,aof原生命令
      • 2.2,aof重写
    • 3,rdb和aof优缺点
    • 4,rdb和aof混合持久化

一,redis的持久化机制和原理

在平常开发中,redis一般是做为缓存使用,但是在很多大型互联网公司中,都是很依赖redis,将数据存储在redis中,如果redis挂了,那么在重启之后内部的数据就会丢失,因此在redis层面,需要对内部的数据进行持久化。在redis持久化中,主要有两种方式:rdb和aof

1,RDB持久化

1.1,save方式实现

在redis中,默认使用的就是rdb这种持久化方式,可以通过redis中安装的redis.conf配置文件查看。redis配置的策略如下,可以通过配置save命令来实现持久化的的操作,在一定的时间段,配置一定的阈值,当触发到阈值时,将内存中的数据进行持久化。

save 900 1     # 在 900 秒内至少有 1 次写操作,进行快照
save 300 10    # 在 300 秒内至少有 10 次写操作,进行快照
save 60 10000  # 在 60 秒内至少有 10000 次写操作,进行快照

接下来通过详细案例测试一下,为了测试这个快照,我这边先修改一下配置,在一分钟内,只要有一次写入,那么就会触发这个快照机制

save 60 1  # 在 60 秒内至少有 1 次写操作,进行快照
CONFIG SET save "60 1" //直接在客户端里面操作,和上面这种方式2选1    

随后先清空原有的dump.rdb文件,此时redis中的rdb文件被清空,或者为了测试的话,可以直接先清空所有的key-value,通过 FLUSHALL 命令即可,但是如果是线上环境需谨慎操作

truncate -s 0 dump.rbd

在这里插入图片描述

随后执行几条插入操作的命令,插入完之后,最后在执行以下save命令。在执行命令如果报错error的话,那是因为没满足阈值触发的条件,最好和我一样,改成60s有一次写入就触发存储的机制

set zhenghuisheng:age 18
set zhenghuisheng:height 18
set zhenghuisheng:sex 18    

在这里插入图片描述

随后可以直接查看这个dumo.rdb文件,可以发现数据已经全部存进rdb文件中

在这里插入图片描述

通过数据可以得知,rdb文件是一种二进制文件,更加的适配与操作系统,如果宕机了想要数据恢复的话,那么使用这种二进制文件恢复肯定是效率最高的。

但是如果是使用这种save的方式进行持久化,也会带来部分性能问题,因为save这种方式是采用的 同步 的方式进行数据存储,安全性高,但是如果来了一个 大key,就是一个大对象,如果存一个大对象就要5s,那么此时整个redis都会被阻塞5s,跟内部的反应堆模式有关,那么就会严重影响redis的性能

1.2,bgsave的实现

既然上面的save会由于同步带来一些性能的问题,因此redis也给出了另一份解决思路,就是通过bgsave异步的方式来实现这个rdb快照,从而提高整体的性能的吞吐量。bgsave,即background,后台存储的意思

接下来依旧先演示一下bgsave的使用,先执行三条插入数据的命令,随后执行 bgsave 进行数据存储

set bgsave:001 test1
set bgsave:002 test2
set bgsave:003 test3

在这里插入图片描述

结果如下图,此时三条命令也已二进制的方式存入到dump.db的配置文件中

在这里插入图片描述

bgsave通过 写时复制(copy-on-write) 的方式实现异步操作,就是执行bgsave的主线程,在执行bgsave命令的那一刻,会fork出一个子线程来copy主线程中的所有数据,并且此时如果还有数据写入进来,会同时操作原主线程中的内存数据和新fork出现的子线程中的数据。

既然是使用异步的方式进行数据的持久化,那么就有可能会不安全,数据丢失等问题。

1.3,rdb的优缺点

优点

使用rdb的优点在于,内部采用的是二进制的方式进行数据存储,存储效率较高,如果宕机了要进行数据恢复的话,那么数据恢复也相对较快

缺点

缺点也很明显,首先就是选择存储的方式,即save和bgsave的方式,就是经典的高性能和高可用之间做选择。采用save方式可用保证高可用,数据相对安全,但是可能会出现整个系统出现阻塞问题;采用bgsave方式,通过写时复制的异步方式进行数据的存储,性能相对较快,但是可能造成数据丢失等不安全问题。

还有一个主要的问题,rdb是通过某种阈值触发的条件实现rdb存储,假设5分钟达到1000条命令存储一次,那么如果在这5分钟内的数据刚好到达了阈值临界点,但是此时redis宕机了,导致这5分钟的数据没有进行rbd的持久化,那么就可能会丢失5分钟的数据,在重启redis进行数据恢复的时候,这5分钟的数据将不能恢复

2,AOF持久化

虽然说在redis中默认的是使用rdb这种方式进行持久化,但是rdb这种方式很明显,可能会造成数据丢失比较多的情况,比如一个1w qps/s的系统,假设丢5分钟数据,那么就会丢失掉300万条数据,显然使用默认的方式是不太合理的

100000 * 60 * 5 = 300 0000

2.1,aof原生命令

因此redis引入了aof文件日志写入的这种操作,在redis.conf配置文件中,打开 appendonly 设置为yes即可

appendonly yes
CONFIG SET appendonly yes  //直接在客户端中操作,和上面这种方式的效果一样    

在开启完aof命令之后,接下来再往redis中插入几条数据

set aof:test1 aof1
set aof:test2 aof2
set aof:test3 aof3

在这里插入图片描述

数据插入完成之后,接下来查看这个appendonly.aof文件里面到底存的是什么,由于前期aof一直是开着,因此这里只看后面几条命令即可,如果直接cat把数据直接全部的加载到内存里面,把内存撑爆,导致线上的redis服务器宕机了,那就得不偿失了

//查看尾部几条命令
tail -f appendonly.aof

在这里插入图片描述

可以发现里面就是一些原生执行命令。然后加一些redis内部的一些识别符,在数据进行恢复的时候,可以供内部的c++程序所识别,从而实现数据的恢复。实现数据恢复也比较简单,就是把这些命令从上往下的全部的执行一遍,然后就能将数据恢复。

aof持久化也有对应的策略,其持久化的方式有以下三种,默认采用 appendfsync everysec 每秒同步一次数据

  • appendfsync always:每次写入操作都会立即将数据同步到磁盘。安全性最高,但性能最低。
  • appendfsync everysec:每秒同步一次数据,这是默认选项,性能和安全性之间的折中。
  • appendfsync no:由操作系统决定何时同步数据,这样性能最好,但在崩溃时可能丢失一些数据。

到这里为止,丢失问题的情况依旧存在,比如将1s内的数据再提交到对应的日志文件的时候,rdis宕机了,这就会导致可能丢失1秒钟的数据,相对于上面的rdb,已经属于是优化的操作。

但是aof也有属于自己的缺点,rdb采用的是二进制的压缩文件,文件大小相对较小,在做数据拷贝或者恢复的时候相对较快;而aof都是记录原生的命令,包括记录一些字符串长度等等,随着数据的增加,aof文件会越来越大,一次其数据拷贝或者做数据恢复会相对缓慢

2.2,aof重写

上面谈到了aof的缺点,会随着时间的推移,文件变得很大,甚至可能不小心一个cat命令,直接把服务器的内存打满,导致redis宕机这种可能,因此aof内部添加了aof重写功能。

举个例子,假设一个减库存的操作,假设商品id为1001,数量有10000件,那么预扣减内存的命令就如下

set 1001:stock 9999
set 1001:stock 9998
set 1001:stock 9997    

就是很明显,这个key不变,但是value在变,如果用aof存的话,可能要存10000条数据,那么aof重写的机制就是,只记录最终值。比如商品卖了5000件,常规的aof就存了5000条数据,但是通过aof重写优化之后,只存最终结果即可,这样在日志中只需要存一条,最后数据恢复时也只需要恢复这条最终的命令即可,其他的数据对于整个系统来讲都是垃圾数据。

set 1001:stock 5000

aof重写策略如下,如在文件达到32m时触发一次重写,在64m时又触发一次… 依次类推

auto-aof-rewrite-percentage:100% 触发AOF重写时,文件大小相对于上一次重写时的百分比阈值
auto-aof-rewrite-min-size:32m    触发AOF重写时,AOF文件的最小大小  
    
//可以通过命令方式设置
CONFIG SET auto-aof-rewrite-percentage 100
CONFIG SET auto-aof-rewrite-min-size 32mb    

除了上面的设置之外,也可以手动的方式触发aof重写,就是通过执行这个 BGREWRITEAOF命令

BGREWRITEAOF

通过aof重写的方式,减少aof存储文件的大小,从而提高在数据做主从架构或者恢复时的效率

3,rdb和aof优缺点

通过上面的分析,接下来可以对rdb和aof二者之前做一个全面的对比。

rdbaof
实现方式save、bgsave原生方式、aof重写
存储方式二进制压缩存储文本命令存储
宕机恢复恢复速度快恢复速度慢
数据安全安全性较低安全性高,最多丢1s数据
启动优先级低,优先级低高,优先使用
主从同步不使用,同步数据少使用,可以同步更多数据

在实际开发中,也是可以优先的考虑使用aof的方式来设计持久化问题,并且不管是在数据做同步上,还是数据恢复上,aof的优势还是占优,都能获取到更多的数据,从而保证系统的高可用。

4,rdb和aof混合持久化

在redis4.0之后,引入了一个新的持久化方式,就是可以让rdb持久化和aof持久化结合使用。rdb的优点是采用二进制存储,存储内容效,aof的优点是存储的数据量多,数据丢失量少,因此结合二者优点,让rbd和aof混合持久化。

在使用这个混合持久化之前,分别需要开启aof持久化和混合持久化的命令。

# 启用AOF持久化
appendonly yes
# 启用混合持久化
aof-use-rdb-preamble yes

以aof的维度来讲,肯定是想减少文件的容量大小,并且恢复速度快点,以rdb的维度来讲,肯定是想多存点数据,因此根据这二者维度,可以在aof文件重写之后,将数据转成二进制的格式存到文件中,通过这种方式,通过aof来解决数据丢失问题,又通过rdb文件格式来减少空间存储,并且能再宕机之后更快的恢复数据。

还是通过上面的库存例子详细的说明一下到底什么是混合持久化,首先是开启aof持久化和混合持久化,其次是开启aof的重写功能

auto-aof-rewrite-percentage:100 触发AOF重写时,文件大小相对于上一次重写时的百分比阈值
auto-aof-rewrite-min-size:32m    触发AOF重写时,AOF文件的最小大小 

随后扣减10次库存,为了演示这个文件中的数据,先将 appendonly.aof 文件先清空

truncate -s 0 appendonly.aof 

在这里插入图片描述

随后执行10条扣减库存的操作,如下图,每次对库存进行减1的操作

在这里插入图片描述

执行完成之后,由于此时并没有触发到aof的重写机制,因此需要手动命令进行触发

BGREWRITEAOF

在这里插入图片描述

最后直接查看这个 appendonly.aof 文件,可以发现有部分的二进制文件,有部分的原生命令文件。

就是说那1s的数据会通过rdb的二进制文件进行持久化,在持久化的时候依旧有命令进来,那么暂时先用aof文件进行存储,在下一秒又将前一秒的数据转换成二进制文件存储,通过这种方式最多也只会丢一秒的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2156714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2025校招内推-招联金融

【投递方式】 直接扫下方二维码,或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus,使用内推码 igcefb 投递) 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…

CentOS Stream 9部署docker,并开启API

1、安装docker (1)安装Docker的依赖项和存储库 sudo dnf install -y dnf-plugins-core sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo (2)安装Docker sudo dnf install -y docke…

0基础学习PyTorch——最小Demo

大纲 环境准备安装依赖 训练和推理训练生成数据加载数据TensorDatasetDataLoader 定义神经网络定义损失函数和优化器训练模型 推理 参考代码 PyTorch以其简洁直观的API、动态计算图和强大的社区支持,在学术界和工业界都享有极高的声誉,成为许多深度学习爱…

yum 集中式安装 LNMP

目录 安装 nginx 安装 mysql 安装 php 配置lnmp 配置 nginx 支持 PHP 解析 安装 nginx 修改yum源 将原本的yum源备份 vim /etc/yum.repos.d/nginx.repo [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/7/$basearch/ gpgcheck0 enable…

黎巴嫩BP机爆炸事件启示录:我国应加快供应链安全立法

据报道,当地时间9月17日下午,黎巴嫩首都贝鲁特以及黎巴嫩东南部和东北部多地都发生了BP机爆炸事件。当时的统计数据显示,爆炸造成9人死亡,约2800人受伤。9月18日,死亡人数上升到11人,受伤人数超过4000。 目…

14年数据结构

第一题 解析: 求时间复杂度就是看程序执行了多少次。 假设最外层执行了k次,我们看终止条件是kn,则: 有, 内层是一个j1到jn的循环,显然执行了n次。 总的时间复杂度是内层外层 答案选C。 第二题 解析: 一步一…

车辆行人转向意图状态检测系统源码分享

车辆行人转向意图状态检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of …

【Python】Maya:为人类打造的 Python 日期时间库

不知道少了什么,总感觉没有以前快乐。 在编程中处理日期和时间总是一个挑战,尤其是当涉及到时间和时区的转换时。Maya 是一个由 Kenneth Reitz 开发的 Python 库,旨在简化日期时间的处理,使其对人类开发者更加友好。本文将介绍 M…

如何在jupyter notebook中使用虚拟环境

一:在cmd中打开已经创建好的虚拟环境 二:安装ipykernel conda install ipykernel 三:安装牛逼conda conda install -c conda-forge nb_conda 四:运行jupyter notebook,选择虚拟环境

linux强制关闭再启动后zookeeper无法启动

1、若开启了zkserver就先关闭zkserver 查看zkserver是否启动 sh zkServer.sh status关闭zkServer sh zkServer.sh stop2、更改conf/zoo.cfg 将这里的启动端口改为2183 3、启动zkServer sh zkServer.sh start4、以2183端口启动zkCli zkCli.sh -server 127.0.0.1:2183这样启…

传知代码-基于多尺度动态卷积的图像分类

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 在计算机视觉领域,图像分类是非常重要的任务之一。近年来,深度学习的兴起极大提升了图像分类的精度和效率。本文将介绍一种基于动态卷积网络(Dynamic Convolutional Netw…

机器人机构、制造

简单整理一下,在学习了一些运动学和动力学之类的东西,简单的整合了一些常用的机械结构和图片。 1.电机: 市面上的电机有:直流电机,交流电机,舵机,步进电机,电缸,无刷电…

【无人机设计与控制】 基于matlab的蚁群算法优化无人机uav巡检

摘要 本文使用蚁群算法(ACO)优化无人机(UAV)巡检路径。无人机巡检任务要求高效覆盖特定区域,以最小化能源消耗和时间。本研究提出的算法通过仿生蚁群算法优化巡检路径,在全局搜索和局部搜索中平衡探索与开…

【软件工程】成本效益分析

一、成本分析目的 二、成本估算方法 三、成本效益分析方法 课堂小结 例题 选择题

深度之眼(三十)——pytorch(一)--深入浅出pytorch(附安装流程)

文章目录 一、前言一、pytoch二、六个部分三、如何学习四、学习路径(重要)五、安装pytorch5.1 坑15.2 坑2 一、前言 我看了下目录 第一章和第二章都是本科学的数字图像处理。 也就是这一专栏:数字图像实验。 所以就不准备学习前两章了,直接…

一文详解大语言模型Transformer结构

目录 1. 什么是Transformer 2. Transformer结构 2.1 总体结构 2.2 Encoder层结构 2.3 Decoder层结构 2.4 动态流程图 3. Transformer为什么需要进行Multi-head Attention 4. Transformer相比于RNN/LSTM,有什么优势?为什么? 5. 为什么说Transf…

MySQL --数据类型

文章目录 1.数据类型分类2.数值类型2.1 tinyint类型2.2 bit类型2.3小数类型2.31float2.32decimal 3.字符串类型3.1 char3.2varchar3.3 char和varchar比较 4.日期和时间类型5.enum和set 1.数据类型分类 2.数值类型 2.1 tinyint类型 数值越界测试: create table tt1…

C++ Qt 之 QPushButton 好看的样式效果实践

文章目录 1.前序2.效果演示3.代码如下 1.前序 启发于 edge 更新 web 页面,觉得人家做的体验挺好 决定在Qt实现,方便以后使用 2.效果演示 特性介绍: 默认蓝色鼠标移入 渐变色,鼠标变为小手鼠标移出 恢复蓝色,鼠标恢…

计算机毕业设计之:基于uni-app的校园活动信息共享系统设计与实现(三端开发,安卓前端+网站前端+网站后端)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

006——队列

队列: 一种受限的线性表(线性逻辑结构),只允许在一段进行添加操作,在另一端只允许进行删除操作,中间位置不可操作,入队的一端被称为队尾,出队的一端被称为队头,在而我们…