六、Redis之数据持久化及高频面试题

6.1 数据持久化

官网文档地址:https://redis.io/docs/manual/persistence/

Redis提供了主要提供了 2 种不同形式的持久化方式:

  • RDB(Redis数据库):RDB 持久性以指定的时间间隔执行数据集的时间点快照。
  • AOF(Append Only File):AOF 持久化记录服务器接收到的每个写操作,在服务器启动时再次播放,重建原始数据集。 命令使用与 Redis 协议本身相同的格式以仅附加方式记录。 当日志变得太大时,Redis 能够在后台重写日志。

6.1.1 RDB

6.1.1.1 什么是 RDB

在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是Snapshot快照,它恢复时是将快照文件直接读到内存里。

6.1.1.2 如何备份

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束后,再用这个临时文件替换上次持久化好的文件。主进程不进行任何的IO操作,这样就保证了较高的性能。如果需要进行大规模数据的恢复,并且对于数据恢复的不完整性非常敏感,那么RDB方式会比AOF方式更加高效。注意点:最后一次持久化后的数据可能丢失。

6.1.1.3 Fork

Fork的作用是复制一个与当前进程一样的进程,且新进程内的所有数据(变量,环境变量,程序计数器等等)数值都和原进程一直,但它是一个全新的进程,并且作为原进程的子进程。

在 Linux 程序中,fork() 会产生一个和父进程完全相同的子进程,但子进程在此后多会 exec 系统调用,出于效率考虑,Linux 中引入了“写时复制技术”。

一般情况下,父进程和子进程会共用一段物理内存,只有进程空间的各段内容发生变化时,才会将父进程的内容复制一份给子进程。
在这里插入图片描述

6.1.1.4 备份和恢复
#dump.rdb存放在两个位置上
1、root\          目录    =====>通过正常的启动和关闭所保存的地址
2、var\lib\redis\ 目录    =====>通过 systemctl restart redis 命令所生成的
我们如果要进行备份还原的实验的话,确定目标地址,并选择适配的命令去观察变化
#步骤1:清空数据库
FLUSHALL
#步骤2:
客户端退出  exit
服务器关闭  ctrl+c
#步骤3:观察root\ 内的dump.rdb文件大小 发现是 92
#步骤4:正常启动redis并登录客户端
服务器启动  redis-server
客户端登录  redis-cli
#步骤5:保存了六组信息
set k1 v1 
.......
set k6 v6
#步骤7:
客户端退出  exit
服务器关闭  ctrl+c
#步骤8:观察root\ 内的dump.rdb文件大小 发现是 139
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#步骤9 将139大小的dump.rdb复制 命名为 dump.rdb.back
cp dump.rdb dump.rdb.back
#步骤10 删除dump.rdb
rm -f dump.rdb
#步骤11:正常启动redis并登录客户端,查看数据
服务器启动  redis-server
客户端登录  redis-cli
客户端查看  keys *   ======================>  数据没有了
#步骤12
客户端退出  exit
服务器关闭  ctrl+c
#步骤13:观察root\ 内的dump.rdb文件大小 发现是 92
#步骤14:将139大小的dump.rdb.back复制 命名为 dump.rdb
#步骤15:正常启动redis并登录客户端,查看数据
服务器启动  redis-server
客户端登录  redis-cli
客户端查看  keys *   ======================>  数据存在

6.1.2 AOF

6.1.2.1 什么是AOF

以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据。简单说,Redis 重启时会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

在Redis的默认配置中AOF(Append Only File)持久化机制是没有开启的,要想使用AOF持久化需要先开启此功能。AOF持久化会将被执行的写命令写到AOF文件末尾,以此来记录数据发生的变化,因此只要Redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集。

6.1.2.2 持久化流程

在这里插入图片描述

  1. 客户端的请求写命令会被append追加到AOF缓冲器内。

  2. AOF缓冲区根据AOF持久化策略,将sync同步到磁盘的AOF文件中

  3. AOF文件大小超过了重写策略或手动重写时,会对AOF文件进行重写,以压缩AOF文件容量

  4. Redis服务重启时,会重新load加载AOF文件中的写操作,已达到数据恢复的目的。

6.1.2.3 备份和恢复
#步骤1 开启AOF
修改 redis.conf 配置文件:
- 通过修改redis.conf配置中`appendonly yes`来开启AOF持久化
- 通过appendfilename指定日志文件名字(默认为appendonly.aof)
- 通过appendfsync指定日志记录频率
选项同步频率
always每个redis写命令都要同步写入硬盘,严重降低redis速度
everysec每秒执行一次同步显式的将多个写命令同步到磁盘
no由操作系统决定何时同步
#步骤2 重启服务以确保配置文件被重新读过
systemctl restart redis
#步骤3 在var/lib/redis目录内找到了 appendonly.aof
#步骤4:登录客户端并保存数据
客户端登录  redis-cli
#步骤5:保存了六组信息
set k1 v1 
.......
set k6 v6
#步骤6:基于客户端关闭连接和服务
SHUTDOWN
#步骤7:在var/lib/redis目录内找到了 appendonly.aof  (大小由0变成了一组数值)
#步骤8:复制appendonly.aof 
cp appendonly.aof  appendonly.aof.back
#步骤9:重启服务连接客户端
systemctl restart redis
客户端登录  redis-cli
#步骤10:清空数据库并停止服务
FLUSHDB
SHUTDOWN
#步骤11:在var/lib/redis目录内找到了 appendonly.aof  (大小由一组数值变成了另一组数值 后数值>前数值)
#步骤12:复制appendonly.aof.back
cp appendonly.aof.back  appendonly.aof
#步骤13:重启服务连接客户端
systemctl restart redis
客户端登录  redis-cli
#步骤14:检查数据
keys *

6.1.3 如何选择

那么,在开发中是选择 RDB 还是选择 AOF 来持久化呢?

官网建议如下:

Ok, so what should I use?

The general indication you should use both persistence methods is if you want a degree of data safety comparable to what PostgreSQL can provide you.

If you care a lot about your data, but still can live with a few minutes of data loss in case of disasters, you can simply use RDB alone.

There are many users using AOF alone, but we discourage it since to have an RDB snapshot from time to time is a great idea for doing database backups, for faster restarts, and in the event of bugs in the AOF engine.

The following sections will illustrate a few more details about the two persistence models.

  • RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储

  • AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.

  • Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大

  • 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.

  • 同时开启两种持久化方式

  • 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据, 因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.

  • RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?

  • 建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份), 快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。

6.2 高频面试题

6.2.1 缓存穿透

6.2.1.1 描述

用户想要查询某个数据,在 Redis 中查询不到,即没有缓存命中,这时就会直接访问数据库进行查询。当请求量超出数据库最大承载量时,就会导致数据库崩溃。这种情况一般发生在非正常 URL 访问,目的不是为了获取数据,而是进行恶意攻击。

在这里插入图片描述

6.2.1.2 现象
  1. 应用服务器压力变大

  2. Redis缓存命中率降低

  3. 一直查询数据库

6.2.1.3 原因

一个不存在缓存及查询不到的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

6.2.1.4 解决

① 对空值缓存:如果一个查询数据为空(不管数据是否存在),都对该空结果进行缓存,其过期时间会设置非常短。

② 设置可以访问名单:使用bitmaps类型定义一个可以访问名单,名单id作为bitmaps的偏移量,每次访问时与bitmaps中的id进行比较,如果访问id不在bitmaps中,则进行拦截,不允许访问。

③ 采用布隆过滤器:布隆过滤器可以判断元素是否存在集合中,他的优点是空间效率和查询时间都比一般算法快,缺点是有一定的误识别率和删除困难。

④ 进行实时监控:当发现 Redis 缓存命中率急速下降时,迅速排查访问对象和访问数据,将其设置为黑名单。

6.2.2 缓存击穿

6.2.2.1 描述

key中对应数据存在,当key中对应的数据在缓存中过期,而此时又有大量请求访问该数据,由于缓存中过期了,请求会直接访问数据库并回设到缓存中,高并发访问数据库会导致数据库崩溃。

在这里插入图片描述

6.2.2.2 现象
  1. 数据库访问压力瞬时增加

  2. Redis中没有出现大量 Key 过期

  3. Redis正常运行

  4. 数据库崩溃

6.2.2.3 原因

由于 Redis 中某个 Key 过期,而正好有大量访问使用这个 Key,此时缓存无法命中,因此就会直接访问数据层,导致数据库崩溃。

最常见的就是非常“热点”的数据访问。

6.2.2.4 解决

① 预先设置热门数据:在redis高峰访问时期,提前设置热门数据到缓存中,或适当延长缓存中key过期时间。

② 实时调整:实时监控哪些数据热门,实时调整key过期时间。

③ 对于热点key设置永不过期。

6.2.3 缓存雪崩

6.2.3.1 描述

key中对应数据存在,在某一时刻,缓存中大量key过期,而此时大量高并发请求访问,会直接访问后端数据库,导致数据库崩溃。

注意:缓存击穿是指一个key对应缓存数据过期,缓存雪崩是大部分key对应缓存数据过期。

正常情况下:

在这里插入图片描述

缓存失效瞬间:

在这里插入图片描述

6.2.3.2 现象
  • 数据库压力变大导致数据库和 Redis 服务崩溃
6.2.3.3 原因

在极短时间内,查询大量 key 的集中过期数据。

6.2.3.4 解决

① 构建多级缓存机制:nginx缓存 + redis缓存 + 其他缓存。

② 设置过期标志更新缓存:记录缓存数据是否过期,如果过期会触发另外一个线程去在后台更新实时key的缓存。

③ 将缓存可以时间分散:如在原有缓存时间基础上增加一个随机值,这个值可以在1-5分钟随机,这样过期时间重复率就会降低,防止大量key同时过期。

④ 使用锁或队列机制:使用锁或队列保证不会有大量线程一次性对数据库进行读写,从而避免大量并发请求访问数据库,该方法不适用于高并发情况。

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

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

相关文章

whisperspeech 英文TTS的实现

以下代码成功运行在 colab 中,需要修改运行时类型为 T4 GPU。 !pip install -Uqq WhisperSpeech def is_colab():try: import google.colab; return Trueexcept: return Falseimport torch # if not torch.cuda.is_available(): # if is_colab(): raise BaseEx…

浅谈Linux环境

冯诺依曼体系结构: 绝大多数的计算机都遵守冯诺依曼体系结构 在冯诺依曼体系结构下各个硬件相互配合处理数据并反馈结果给用户 其中控制器和运算器统称为中央处理器(CPU),是计算机硬件中最核心的部分,像人类的大脑操控…

sql语句学习(二)--增删改

数据库的表结构 插入操作 添加操作分为分为单行添加和多行添加。 单行添加 语法格式①:INSERT INTO student(列表1,列表2,列表3,列表4,列表5,列表6) VALUES (值1,值1 , 值1 , 值1 , 值1 ,值1); INSERT INTO student(name,sex,age,sno,class_num) VALUES (hah,…

测试模型基线能力之有手就行PromptBench

以前我说过微软出的AI开源没几个有用的,deepspeed,Autogen算两个,今天我觉得有必要加一个promptbench 我相信我的读者,或多或少对模型训练是有概念的,再不济微调也是玩过的,同时我也相信百分之80以上的读者,是没有对模型进行基线能力评测的经验的 其实究其原因,方法论缺…

汽车零部件制造业MES系统解决方案

一、​汽车零部件行业现状 随着全球汽车产业不断升级,汽车零部件市场竞争日趋激烈,从上游的钢铁、塑料、橡胶等生产到下游的主机厂配套制造,均已成为全球各国汽车制造大佬战略目标调整的焦点,其意欲在汽车零部件行业快速开疆扩土&…

Days 32 ElfBoard GDT工作原理

GDT(Gas Discharge Tubes),即陶瓷气体放电管。GDT是内部由一个或一个以上放电间隙内充有惰性气体构成的密闭器件。GDT电气性能取决于气体种类、气体压力、内部电极结构、制作工艺等因素。GDT可以承受高达数十甚至数百千 安培的浪涌电流冲击&a…

自定义Spring Boot Starter

引言 在Spring Boot的世界中,Starter 能够简化我们的开发过程,通过封装常见的依赖和自动配置。本篇旨在为有志于进一步简化Spring Boot应用配置的开发者提供指导,让我们一起创建一个自定义的Spring Boot Starter。 一、什么是 Spring Boot …

浅谈基于中台模式的大数据生态体系的理解

这篇文章主要浅谈一下我对大数据生态体系建设的理解。 大数据生态系统为高并发,高吞吐,高峰值,高堆积等大规模数据的采集,处理,计算,存储,服务提供了完善的处理体系,致力于打造核心数…

springboot190基于springboot框架的工作流程管理系统的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

机器学习12-基本感知器

感知器(Perceptron)是一种最简单的人工神经网络结构,由美国心理学家Frank Rosenblatt在1957年提出。它是一种单层的前馈神经网络,通常用于二分类问题。 基本感知器由多个输入节点、一个输出节点和一组权重参数组成。每个输入节点都与输出节点连接,并且具有一个对应的权重参…

力扣36.有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 注…

VSCode无法连接远程服务器的两种解决方法

文章目录 VSCode Terminal 报错解决方式1解决方式2you are connected to an OS version that is unsupported by Visual Studio Code解决方法 VSCode Terminal 报错 直接在terminal或cmd中使用ssh命令可以连接服务器,但是在vscode中存在报错,最后一行为…

kali无线渗透之WEP加密模式与破解13

WEP加密是最早在无线加密中使用的技术,新的升级程序在设置上和以前的有点不同,功能当然也比之前丰富一些。但是随着时间的推移,人们发现了WEP标准的许多漏洞。随着计算能力的提高,利用难度也越来越低。尽管WEP加密方式存在许多漏洞…

【C++】const、static关键字和构造函数初始化

💗个人主页💗 ⭐个人专栏——C学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 1. const修饰成员函数 1.1 语法格式 1.2 权限放大缩小 1.3 思考 1.4 解答 2. 再谈构造函数 2.1 构造函数体赋值 2.2 初始…

书生浦语大模型实战营-课程笔记(1)

模型应用过程,大致还是了解的。和之前实习做CV项目的时候比起来,多了智能体这个环节。智能体是个啥? 类似上张图,智能体不太清楚。感觉是偏应用而不是模型的东西? 数据集类型很多,有文本/图片/视频。所以…

代码随想录算法训练营Day32 | 122.买卖股票的最佳时机 II、55.跳跃游戏、45.跳跃游戏 II

122.买卖股票的最佳时机 II 这题感觉还是偏简单的,主要是要理解一点:本题中股票能当天买入当天卖出且能得知明天的股票价格 这个设定省去了很多麻烦,每天先无脑买入即可,如果第二天价格更高就第二天卖出,如果第二天价…

IDEA玩转Git

GIT 基本概念 本地版本控制 git add git commit git checkout Git - Reference 向日葵下载地址:向日葵远程控制app官方下载 - 贝锐向日葵官网 远程库

【Java】笔记:JDBC中Statement常用的几个执行函数

1.executeQuery(String sql): ResultSet 用于执行查询语句(SELECT),返回一个 ResultSet 对象,该对象包含了查询结果的数据。可以通过 ResultSet 提供的方法来获取查询结果。 //声明statement Statement statement connection.c…

神要封,仙要修

(1)人间之战 我记得,那一年,西方的胡夫正要开始修建他的死后极乐世界:金字塔。 那一年,东方也爆发了一场人间大战。 很久很久以前,一支来自乌拉尔山脉南麓脚下的游牧部落,骑着马赶着…

ATCoder Beginner Contest 340 A~G

A.Arithmetic Progression&#xff08;模拟&#xff09; 题意&#xff1a; 输出首项为 a a a&#xff0c;末项为 b b b&#xff0c;公差为 d d d的等差数列。 分析&#xff1a; 按照要求模拟。 代码&#xff1a; #include <bits/stdc.h>using namespace std;int ma…