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

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

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文件进行存储,在下一秒又将前一秒的数据转换成二进制文件存储,通过这种方式最多也只会丢一秒的数据。

相关文章:

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

redis系列整体栏目 内容链接地址【一】redis基本数据类型和使用场景https://zhenghuisheng.blog.csdn.net/article/details/142406325【二】redis的持久化机制和原理https://zhenghuisheng.blog.csdn.net/article/details/142441756 如需转载,请输入:htt…...

亚马逊IP关联揭秘:发生ip关联如何处理

在亚马逊这一全球领先的电商平台上,IP关联是一个不可忽视的问题,尤其是对于多账号运营的卖家而言。本文将深入解析亚马逊IP关联的含义、影响以及应对策略,帮助卖家更好地理解和应对这一问题。 什么是亚马逊IP关联? 亚马逊IP关联…...

jQuery Mobile 弹窗

jQuery Mobile 弹窗 引言 在移动设备上,弹窗是一种常见的用户界面元素,用于显示信息、获取用户输入或提供特定功能。jQuery Mobile 是一个流行的移动框架,它提供了丰富的组件来帮助开发者创建响应式的移动界面。本文将重点介绍如何在 jQuery Mobile 中使用弹窗(Popup)组…...

【macOS】【zsh报错】zsh: command not found: python

【macOS】【zsh Error】zsh: command not found: python 本地已经安装了Python,且能在Pycharm中编译Python程序并运行。 但是,在macOS终端,运行Python,报错。 首先要确认你在macOS系统下,是否安装了Python。 如果安…...

NoSql数据库Redis知识点

数据库的分类 关系型数据库 ,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库 中的数据主流的 MySQL 、 Oracle 、 MS SQL Server 和 DB2 都属于这类传统数据库。 NoSQL 数据库 ,全称为 Not Only SQL &a…...

Redis 使用指南

Redis 使用指南 概述 Redis 是一个开源的、基于内存的数据结构存储系统,可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(strings)、哈希(hashes)、列表(lists&#xf…...

c++与cmake:完整的C++项目构建注意事项

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 最近常常使用cmake构建c项目有感,从创建项目到打包发布总结一下需要注意的事情. 项目组织方式 具体的项目组织方式因人而异,这里推荐一种,在src目录中创建模块目录,再在include目录中常见对应的同名目录包含头文件,…...

Linux自主学习篇

用户及权限管理 sudo 是 "superuser do" 的缩写,是一个在类 Unix 操作系统(如 Linux 和 macOS)中使用的命令。它允许普通用户以超级用户(root 用户)的身份执行命令,从而获得更高的权限。 useradd…...

MQ入门(4)

Erlang:面向高并发的 单机的吞吐量就是并发性:Rabbitmq是10w左右(现实项目中已经足够用了),RocketMQ是10w到20w,Kafka是100w左右。 公司里的并发(QPS) 大部分的公司每天的QPS大概…...

linux下共享内存的3种使用方式

进程是资源封装的单位,内存就是进程所封装的资源的一种。一般情况下,进程间的内存是相互隔离的,也就是说一个进程不能访问另一个进程的内存。如果一个进程想要访问另一个进程的内存,那么必须要进过内核这个桥梁,这就是…...

伊丽莎白·赫莉为杂志拍摄一组素颜写真,庆祝自己荣膺全球最性感女人第一名

语录:女性应该做任何她们想做的事,批评她们的人都见鬼去吧。 伊丽莎白赫莉为《Maxim》杂志拍摄一组素颜写真,庆祝自己荣膺全球最性感女人第一名 伊丽莎白赫莉 (Elizabeth Hurley) 实在是太惊艳了,如今,《马克西姆》杂…...

Qt快捷键说明与用法

编辑与查找 CtrlF:在当前编辑窗口中查找关键字。支持大小写相关、全词匹配、正则表达式匹配等选项,并且查找之后还可以进行替换操作。 CtrlShiftF:进行全局查找,不局限于当前文件。注意,在某些情况下,这个…...

技术周刊 | TS 5.6、Chrome DevTools 性能面板上新、Vite 6 Beta、Fastify v5、HTTP 新方法 Query

增长能力,就是持续做出正确决定的能力。 大家好,我是童欧巴,欢迎来到第 128 期技术周刊。 资讯 TypeScript 5.6 TypeScript 5.6 如期发布。 Chrome DevTools 发布全新性能功能 Chrome DevTools 的性能面板上新测试,包括 Core…...

使用Mockito进行单元测试

1、单元测试介绍 Mockito和Junit是用于单元测试的常用框架。单元测试即:从最小的可测试单元(如函数、方法或类)开始,确保每个单元都能按预期工作。单元测试是白盒测试的核心部分,它有助于发现单元内部的错误。 单元测试…...

CSS 布局三大样式简单学习

目录 1. css 浮动 1.1 效果1 1.2 效果2 1.3 效果3 1.4 效果4 2. css 定位 2.1 absolute 2.2 relative 2.3 fixed 3. css 盒子模型 3.1 效果1 3.2 效果2 3.3 效果3 3.4 效果4 1. css 浮动 1.1 效果1 1.2 效果2 1.3 效果3 1.4 效果4 2. css 定位 2.1 absolute 2.2 …...

集成运放UA741的原理与应用的探索

我们发现TI公司提供了UA741的内部电路,此电路包括22个晶体管,11个电阻,1个二极管,1个电容。 1UA741设计需求 1.1有短路保护 UA741的短路保护功能‌是指当输出端发生短路时,该器件能够自动保护自身,防止因…...

LeetCode337. 打家劫舍III

// 很好的一道题目,既考察递归又考察动归 // 这个版本超时了,原因是暴搜 // 很显然这里使用的是前序,那是不是应该考虑后序?public int rob(TreeNode root) {if (root null) {return 0;}if (root.left null && root.rig…...

python基础(二) 包和import

包的创建 文件创建命令 在 Django 中,python manage.py startapp first_app 这一行命令的作用是创建一个新的应用(app),名为 first_app。在 Django 项目中,"app" 是实现某些功能模块的单独部分&#xff0c…...

选址模型 | 基于混沌模拟退火粒子群优化算法的电动汽车充电站选址与定容(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于混沌模拟退火粒子群优化算法的电动汽车充电站选址与定容(Matlab) 问题建模:首先,需要将电动汽车充电站选址与定容问题进行数学建模,确定目标函数和约束…...

WPF入门教学十 资源与字典

在WPF(Windows Presentation Foundation)中,资源与字典是用于管理和重用UI元素的重要机制。它们不仅有助于保持XAML代码的整洁,还能提升应用程序的性能和可维护性。以下是关于WPF资源与字典的详细说明: 静态资源与动态…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...