基础面试题整理7之Redis

1.redis持久化RDB、AOF

RDB(Redis database)

在当前redis目录下生成一个dump.rdb文件,对redis数据进行备份

常用save、bgsave命令进行数据备份:

  • save命令会阻塞其他redis命令,不会消耗额外的内存,与IO线程同步;
  • bgsave命令不会阻塞其他redis命令,会耗额外内存,与IO线程异步;

bgsave命令是由主线程衍生出来的一个子进程,该子进程可以获取主线程的全部内存数据。若在执行bgsave命令时,还有其他redis命令被执行(主线程数据修改),此时会对数据做个副本,然后bgsave命令执行这个副本数据写入rdb文件,此时主线程还可以继续修改数据。

配置自动生成rdb文件的后台使用bgsave命令

AOF(append-only-file)

在当前redis目录下会生成aof文件,对redis修改数据的命令进行备份

 开启aof方式,并配置aof文件名字

redis命令与AOF文件内容

操作redis,命令如下

可以看到aof文件内容,记录修改数据命令

*为一条命令的开始,*后面的数字为命令的参数个数,$及数字表示该命令的参数长度

 配置redis多久将命令执行到aof文件中

  • appendfsync always:每次有新命令就会追加aof文件中
  • appendfsync everysec:每秒追加到aof文件中,所以可能会丢失一秒钟的数据(默认)
  • appendfsync no:不追加,将数据交给操作系统来负责

AOF重写:定期根据内存的最新数据生成aof文件

由于一些命令一直在修改同一个key的信息,所以有时可以合并为一条命令。例如 set age 1 ->set age 2 ->set age 3,此时可以直接在aof文件写set age 3这一条命令即可。

对应aof文件:

手动重写命令:bgrewriteaof

对应aof文件:

配置自动重写的条件:
  • auto-aof-rewrite-percentage 100: 当aof文件比上一次重写大了100%,触发重写机制
  • auto-aof-rewrite-min-size 64mb:当aof文件大小超过64M,触发重写机制

RDB、AOF区别

  • 由于RDB文件体积小(二进制文件),所以恢复数据速度快;相对AOF文件体积大(命令存储),所以恢复数据速度慢
  • RDB比AOF文件可能丢失数据(RDB是通过save命令设置持久化,所以可能会丢失很多数据;而AOF可能会丢失一秒的数据),相对数据安全,所以一般数据恢复时系统默认使用AOF方式

混合持久化

redis4后可以将RDB、AOF混合使用,速度很快

  1. 混合持久化设置启用 aof-use-rdb-preamble yes,AOF也需要开启,RDB配置可去掉(save命令)
  2. redis数据重写时AOF文件以二进制形式(RDB)存储+增量AOF数据继续以命令存储
  • 考虑redis性能时,无论什么架构,一般对master节点不进行持久化,对slave节点进行AOF持久化
  • 若对master节点不进行持久化,那么不建议运维自动重启master节点,因为重启master节点,数据未做持久化,是个空实例,最后主从同步会导致数据全部丢失。所以建议哨兵模式,哨兵自己判断去重启某个节点

2.缓存击穿、缓存穿透、缓存雪崩

缓存击穿(缓存失效)

某一时刻热点key过期了,同时有大量请求过来,出现查询不到redis数据,都去查询数据库,造成数据库的压力瞬间过大问题;重点是缓存key失效(Redis不存在,数据库存在)

解决办法:

  • 对redis的过期时间设置成不一样
  • 对读取数据库后写入Redis这步骤加个锁,防止并发

缓存穿透

某一时刻大批量不存在的key请求过来,出现查询不到redis数据,都去查询数据库,造成数据库的压力瞬间过大问题;重点是不存在的数据(Redis不存在,数据库也不存在)

解决办法:

  • 参数校验
  • 当数据库也查询不到数据时,给个默认空字符串并设置过期时间,然后在查询redis时数据不为空,对空字符串数据进行判断,伪代码如下:
public String get(String pid) {//1.查询Redis数据String redisInfo = redis.get(pid);if (StringUtils.isNotEmpty(redisInfo)) {//1.1Redis数据为空字符串,读缓存延长if ("{}".equals(redisInfo)) {redis.expire(pid, 1000, TimeUnit.SECONDS);}//1.2Redis数据不为空字符串,也读缓存延长redis.expire(pid, 24 * 60 * 60, TimeUnit.SECONDS);return redisInfo;}//2.查询数据库String daoInfo = dao.get(pid);if (StringUtils.isNotEmpty(daoInfo)) {//2.1数据库查询到数据,并添加缓存到redisredis.set(pid, daoInfo, 24 * 60 * 60, TimeUnit.SECONDS);return redisInfo;} else {//2.2数据库查询不到数据,缓存到redis为空字符串redis.set(pid, "{}", 1000, TimeUnit.SECONDS);}return daoInfo;
}
  • 布隆过滤器 在访问Redis前判断

缓存雪崩

某一时刻大批量的过期key查询Redis查不到,后查询数据库,造成数据库挂掉;重点是大批量不同的过期key

解决办法:

  • Redisson分布式锁

使用分布式锁对商品ID进行控制,因为Redis的执行操作是单线程的,无论哪台服务器,最后都要执行到Redis;若不使用Redisson,而是用synchronized(this),此时会造成对服务器的加锁,若开始大量查询ID为1的商品,每台机器都会先跑一遍加个锁,然后在查询ID为2的数据,此时需要等待ID为1的锁释放,所以需要将this对象调整为全局商品ID。

使用Redis分布式锁+二级缓存(Map<String,Object>)解决

public String get(String pid) {//1.查询Redis数据String redisInfo = redis.get(pid);if (StringUtils.isNotEmpty(redisInfo)) {//1.1Redis数据为空字符串,读缓存延长if ("{}".equals(redisInfo)) {redis.expire(pid, 1000, TimeUnit.SECONDS);}//1.2Redis数据不为空字符串,也读缓存延长redis.expire(pid, 24 * 60 * 60, TimeUnit.SECONDS);return redisInfo;}//2.获取Redis分布式锁RLock hotLock = redissonClient.getLock("lock:"+pid);hotLock.lock();try {//3.重新查询缓存redisInfo = redis.get(pid);if (StringUtils.isNotEmpty(redisInfo)) {if ("{}".equals(redisInfo)) {redis.expire(pid, 1000, TimeUnit.SECONDS);}redis.expire(pid, 24 * 60 * 60, TimeUnit.SECONDS);return redisInfo;}//4.查询数据库String daoInfo = dao.get(pid);if (StringUtils.isNotEmpty(daoInfo)) {//4.1数据库查询到数据,并添加缓存到redisredis.set(pid, daoInfo, 24 * 60 * 60, TimeUnit.SECONDS);return redisInfo;} else {//4.2数据库查询不到数据,缓存到redis为空字符串redis.set(pid, "{}", 1000, TimeUnit.SECONDS);}}finally {hotLock.unlock(); //释放锁}return daoInfo;
}
  •  key的过期时间设置随机数,防止同时过期

3.redis分布式锁

TODO

4.redis主从同步机制 

配置文件中从节点需要记录主节点的ip及端口号信息。主从数据复制时,若是master节点下面有很多slave节点,在某一时刻同时让master节点发送RDB文件给slave节点,会造成主节点压力过大,形成主从复制风暴问题。可以调整为从节点复制从节点的树形复制。

主从复制有全量复制增量复制

全量复制

  • bgsave命令,主线程衍生一个子进程,将持久化RDB文件通过网络传输给从节点
  • 从节点先删除旧数据,然后重新载入RDB文件(此过程是阻塞的)

增量复制

  • 偏移量:主从节点都存储一个偏移量,用于记录增量的offset
  • 复制积压缓冲区:复制到持久化RDB文件之前有个积压缓冲区,这样主从复制速度快些
  • 服务器运行ID:每个节点启动时自动生成一个服务器运行ID,然后主从节点都会互相发送并存储这个ID,每次增量复制会判断运行ID,若与之前存储的ID不同,则需要全量复制;否则增量复制

5.redis数据备份

数据备份模式一般都是大同小异的(无论是redis还是日志等其他文件数据)

  • 对RDB文件或AOF文件进行定时备份到另一台机器中,保留72小时的备份(时间以项目情况为准)
  • 每天保留一份数据进行备份到另一个目录,保留一个月的备份(时间以项目情况为准)
  • 每次备份时需要将之前的旧数据删除掉

6.redis在电商的使用

  • 一般数据量电商项目中,新增/修改接口都会先入数据库,后将该数据放到redis缓存中[set(key,value)];在查询该商品时,先去redis缓存中读取,若未查询到再去数据库中获取,否则直接返回缓存数据;
  • 海量数据的电商项目中,新增/修改接口在操作redis缓存时,需要给个过期时间[set(key,value,time,unit)];在查询该商品时,从redis缓存读取后,需要将该商品的redis缓存过期时间延长。这样可以实现缓存数据的冷热分离。因为数据的访问量不同,加个过期时间可提高效率
  • 查询接口中当查询数据库时有写操作(修改接口)进来,导致数据库与Redis数据不一致,此时Redis分布式锁有读写锁,需要在读数据库前补充读锁,修改操作补充写锁
  • 布隆过滤器:int[10]共4*8*10=320个字节的位图,用于在查询Redis判断是否存在该数据,若不存在,则直接返回不存在该数据;存在则继续查询Redis; 

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

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

相关文章

Qt 常见容器类用法(二)

目录 QList类 QLinkedList类 QList类 对于不同的数据类型&#xff0c;QList<T>采取不同的存储策略&#xff0c;存储策略如下&#xff1a; 如果T是一个指针类型或指针大小的基本数据类型(该基本类型占有的字节数和指针类型占有的字节数相同)&#xff0c;QList<T>…

《Git 简易速速上手小册》第8章:保护你的代码(2024 最新版)

文章目录 8.1 使用 .gitignore 优化你的仓库8.1.1 基础知识讲解8.1.2 重点案例&#xff1a;为 Python 项目配置 .gitignore8.1.3 拓展案例 1&#xff1a;使用全局 .gitignore8.1.4 拓展案例 2&#xff1a;忽略已经被跟踪的文件 8.2 管理敏感数据8.2.1 基础知识讲解8.2.2 重点案…

少儿编程考级:智慧启迪还是智商税?

在当前科技日新月异的时代背景下&#xff0c;少儿编程教育日益受到家长和社会的广泛关注。与此同时&#xff0c;各类少儿编程考级应运而生&#xff0c;引发了公众对于其价值和意义的深度探讨。一部分人认为这是对孩子逻辑思维与创新能力的有效锻炼&#xff0c;是智慧启迪的重要…

[Python] opencv - 什么是直方图?如何绘制图像的直方图?如何对直方图进行均匀化处理?

什么是直方图&#xff1f; 直方图是一种统计图&#xff0c;用于展示数据的分布情况。它将数据按照一定的区间或者组进行划分&#xff0c;然后计算在每个区间或组内的数据频数或频率&#xff08;即数据出现的次数或占比&#xff09;&#xff0c;然后用矩形或者柱形图的形式将这…

Python(20)正则表达式(Regular Expression)中常用函数用法

大家好&#xff01;我是码银&#x1f970; 欢迎关注&#x1f970;&#xff1a; CSDN&#xff1a;码银 公众号&#xff1a;码银学编程 正文 正则表达式 粗略的定义&#xff1a;正则表达式是一个特殊的字符序列&#xff0c;帮助用户非常便捷的检查一个字符串是否符合某种模…

5.electron之主进程起一个本地服务

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中&#xff0c;因此它允许你仅需一个代码仓库&#xff0c;就可以撰写支持 Windows、…

Multisim14.0仿真(五十五)汽车转向灯设计

一、功能描述&#xff1a; 左转向&#xff1a;左侧指示灯循环依次闪亮&#xff1b; 右转向&#xff1a;右侧指示灯循环依次闪亮&#xff1b; 刹车&#xff1a; 所有灯常亮&#xff1b; 正常&#xff1a; 所有灯熄灭。 二、主要芯片&#xff1a; 74LS161D 74LS04D 74…

谁是嫌疑犯问题

问题描述&#xff1a; 有6名犯罪嫌疑人A、B、C、D、E、F&#xff0c;已知如下事实&#xff1a; A、B至少有1人作案&#xff1b; A、E、F三人中至少有2人参与作案&#xff1b; A、D不可能是同案犯&#xff1b; B、C或同时作案&#xff0c;或与本案无关&#xff1b; C、D中…

[office] Excel如何快速统一数字编号长度 #经验分享#其他

Excel如何快速统一数字编号长度 我们在办公室使用Excel统计数据的时候&#xff0c;经常会遇到第一列数据全部是数字编号&#xff0c;但是因为数字的位数不一样&#xff0c;长短不一的样子看起来不是很协调。那么如何快速统一数字编号长度呢&#xff1f;一起来了解一下吧 我们在…

mac电脑快捷指令实现拼图

mac访达&#xff0c;搜索输入‘快捷指令’&#xff0c;找到‘快捷指令’&#xff0c; 点击快捷指令&#xff0c;进入快捷指令中心&#xff0c;搜索‘拼图’ &#xff0c;选中‘照片拼图’&#xff0c; 点击‘添加快捷指令’&#xff0c; 在‘所有快捷键指令’中可以看到添加的快…

【chromium】windows构建base库 3:gn + vs2022 args 设置及debug x86 构建

GN 构建配置GN 构建配置 此页面提供了 GN 构建的一些常见构建设置。它假设您已经获得了 Chromium checkout。 也可以看看 从命令行运行“gn help”。 所有 GN 文档 GN 快速入门指南 GN 参考 (一个网页中“gn help”中所有内容的转储)。 了解 GN 构建标志 回想一下,在 GN …

tomcat部署zrlog

1.下载zrlog包&#xff0c;并添加到虚拟机中 1)进入/opt/apache-tomcat-8.5.90/webapps目录 cd /opt/apache-tomcat-8.5.90/webapps2)下载zrlog包 wget http://dl.zrlog.com/release/zrlog-1.7.1-baaecb9-release.war 3)重命名包 mv zrlog-1.7.1-baaecb9-release zrblog 2…

【Linux】环境基础开发工具的使用之gdb详解(三)

前言&#xff1a;上一篇文章中我们讲解了Linux下的gcc与g的使用&#xff0c;今天我们将进一步的学习gdb与makefile来帮我们更好的理解与使用基础开发工具。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:Linux的深度刨析 &#x1f448; …

从零开始手写mmo游戏从框架到爆炸(六)— 消息处理工厂

就好像门牌号一样&#xff0c;我们需要把消息路由到对应的楼栋和楼层&#xff0c;总不能像菜鸟一样让大家都来自己找数据吧。 首先这里我们参考了rabbitmq中的topic与tag模型&#xff0c;topic对应类&#xff0c;tag对应方法。 新增一个模块&#xff0c;专门记录路由eternity-…

【类与对象(中)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 引用 常引用 5.赋值运算符重载 5.1…

C语言之找单身狗

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a; 我要学编程(ಥ_ಥ)-CSDN博客 题目&#xff1a; 在一个整型数组中&#xff0c;只有一个数字出现一次&#xff0c;其他数组都是成对出现的&#xff0c;请找出那个只出现一次的数字。…

【zip密码】解除ZIP压缩文件的密码保护的4种方法

Zip压缩包加密大家都很熟悉了&#xff0c;那么zip压缩包取消密码&#xff0c;大家了解多少呢&#xff1f;有密码的情况下&#xff0c;有哪些方法可以取消密码&#xff1f;无密码又该如何取消密码&#xff1f;今天将方法总结分享给大家。 最原始的方法&#xff0c;就是通过解压…

使用GDI画图片生成合成图片并调用打印机进行图片打印

使用GDI画图片生成合成图片并调用打印机进行图片打印 新建窗体应用程序PrinterDemo&#xff0c;将默认的Form1重命名为FormPrinter&#xff0c;添加对 Newtonsoft.Json.dll用于读写Json字符串 zxing.dll&#xff0c;zxing.presentation.dll用于生成条形码&#xff0c;二维码…

DHCP配置

拓扑图 接口地址池 PC5通过接口地址池获取地址&#xff0c;DHCP服务器和VLAN40的网关为SW4 10.0.40.254 SW4 # sysname Huawei # vlan batch 10 20 30 40 # dhcp enable # interface Vlanif40ip address 10.0.40.254 255.255.255.128dhcp select interface # interface Giga…

frp新版toml配置

从frp v0.52.0 版本开始&#xff0c;frp 将TOML作为配置文件格式。INI 格式已被弃用&#xff0c;并将在未来的发布中移除。因此&#xff0c;frp v0.52.0 及更高版本的配置文件默认为TOML格式。 项目地址 GitHub&#xff1a;https://github.com/fatedier/frp/releases 服务端…