Redis面试问题缓存相关详解
Redis面试问题缓存相关详解
一、缓存三兄弟(穿透、击穿、雪崩)
1. 穿透
问题描述:
缓存穿透是指查询一个数据库中不存在的数据,由于缓存不会保存这样的数据,每次都会穿透到数据库,导致数据库压力增大。例如,用户请求一个不存在的用户ID,每次请求都会直接查询数据库。
解决方法:
1.1、存储特殊标记值:
当数据库中没有查询到数据时,可以将一个特殊标记值(如"not_found")存储到Redis中,并设置一个较短的过期时间(如5分钟)。这样,后续的请求可以直接返回"not_found",而不会再次查询数据库。
优点:实现简单,减少数据库压力。
缺点:如果数据库中后来插入了数据,而Redis中仍然缓存了"not_found",会导致查询结果不一致。
示例:
String value = redis.get(key);
if (value == null) {value = database.get(key);if (value == null) {redis.set(key, "not_found", 300); // 缓存5分钟return "not_found";} else {redis.set(key, value, 3600); // 缓存1小时}
}
return value;
1.2、布隆过滤器:
在缓存和数据库之间加入一个布隆过滤器,它可以预存储一些可能存在的键。如果查询的键不在布隆过滤器中,直接返回不存在,避免查询数据库。布隆过滤器通过哈希函数实现,误判率可以通过调整其大小和哈希函数的数量来控制。
优点:减少对数据库的无效查询。
缺点:实现复杂,有一定的误判率。
示例:
if (!bloomFilter.contains(key)) {return "not_found";
}
String value = redis.get(key);
if (value == null) {value = database.get(key);redis.set(key, value, 3600); // 缓存1小时
}
return value;
2. 击穿
问题描述:
缓存击穿是指一个热点数据的缓存过期后,大量请求同时查询数据库,导致数据库压力过大。例如,一个热门商品的详情页缓存过期,大量用户同时请求该页面。
解决方法:
2.1、互斥锁:
使用互斥锁确保只有一个线程可以查询数据库并更新缓存。其他线程等待锁释放后直接从缓存中获取数据。可以使用Redis的SETNX命令实现分布式锁。
示例:
String lockKey = "lock:" + key;
if (redis.setnx(lockKey, "1", 30) == 1) { // 尝试获取锁,超时30秒String value = database.get(key);redis.set(key, value, 3600); // 更新缓存redis.del(lockKey); // 释放锁return value;
} else {// 等待锁释放Thread.sleep(100);return redis.get(key);
}
2.2、逻辑过期:
在缓存中存储一个额外的过期时间字段,每次读取时检查逻辑过期时间。即使Redis的物理过期时间到了,逻辑过期时间仍然有效,可以避免频繁更新缓存。
示例:
String value = redis.get(key);
if (value == null) {String lockKey = "lock:" + key;if (redis.setnx(lockKey, "1", 30) == 1) {value = database.get(key);redis.set(key, value, 3600); // 更新缓存redis.del(lockKey); // 释放锁} else {Thread.sleep(100);return redis.get(key);}
}
return value;
3. 雪崩
问题描述:
缓存雪崩是指大量缓存数据在同一时间过期,导致大量请求同时查询数据库,造成数据库压力过大。例如,多个热点数据的缓存同时过期。
解决方法:
3.1、随机过期时间:
为每个缓存设置不同的过期时间,避免大量缓存同时过期。例如,可以使用SETEX命令为每个key设置随机的过期时间(如1-5分钟)。
示例:
int randomTTL = new Random().nextInt(300) + 60; // 随机过期时间1-5分钟
redis.setex(key, randomTTL, value);
3.2、本地缓存:
在应用层使用本地缓存(如Guava Cache)作为二级缓存,减轻Redis的压力。本地缓存可以快速响应,减少对Redis的依赖。
示例:
LoadingCache<String, String> localCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {return redis.get(key);}});String value = localCache.get(key);
if (value == null) {value = database.get(key);redis.setex(key, 3600, value); // 更新Redis缓存localCache.put(key, value); // 更新本地缓存
}
return value;
3.3、降级限流:
降级和限流是应对高并发场景的通用策略。可以使用Guava RateLimiter或Redis的INCR和EXPIRE命令实现限流。例如,每秒最多允许100次请求:
示例:
RateLimiter rateLimiter = RateLimiter.create(100); // 每秒100次
if (rateLimiter.tryAcquire()) {return handleRequest();
} else {return "Too many requests";
}
二、双写一致
问题描述:
双写一致是指保持Redis和数据库的更新操作一致。如果操作顺序不当,可能会导致数据不一致。例如:
- 先更新Redis,再更新数据库:可能导致Redis中的数据丢失。
- 先更新数据库,再更新Redis:可能导致Redis中的旧数据覆盖新数据。
解决方法:
1、延迟双删:
先删除Redis中的缓存,然后更新数据库,最后再删除一次Redis中的缓存。这样可以确保Redis中的数据是最新的。
示例:
redis.del(key); // 删除缓存
database.update(key, value); // 更新数据库
Thread.sleep(300); // 延迟300毫秒
redis.del(key); // 再次删除缓存
2、分布式锁:
使用分布式锁确保同一时间只有一个线程可以更新数据。可以使用Redisson等库实现分布式锁。
示例:
RLock lock = redisson.getLock("lock:" + key);
try {lock.lock();database.update(key, value); // 更新数据库redis.del(key); // 删除缓存
} finally {lock.unlock();
}
3、共享锁和排它锁:
共享锁:当一个线程在读取数据时,其他线程可以同时读取,但不能写入。
排它锁:当一个线程在写入数据时,其他线程不能读取或写入。
示例:
// 使用Redis的SET命令实现共享锁和排它锁
String lockKey = "lock:" + key;
if (redis.set(lockKey, "1", 30, NX, EX)) { // 获取排它锁database.update(key, value); // 更新数据库redis.del(key); // 删除缓存redis.del(lockKey); // 释放锁
} else {// 等待锁释放Thread.sleep(100);
}
三、持久化
Redis提供了两种持久化方式:RDB和AOF。
1、RDB(快照模式):
优点:恢复速度快,数据完整性好,方便使用。
缺点:可能会丢失最后一次快照之后的数据,占用磁盘空间较大。
配置示例:
save 900 1 # 900秒内至少有1个键被修改时保存快照
save 300 10 # 300秒内至少有10个键被修改时保存快照
2、AOF(追加模式):
优点:数据不易丢失,恢复时可以逐条执行命令。
缺点:文件体积大,恢复速度慢。
配置示例:
appendonly yes
appendfsync everysec # 每秒同步一次
3、混合持久化:
Redis 4.0引入了混合持久化模式,结合了RDB和AOF的优点。可以同时使用两种持久化方式,提高数据安全性和恢复速度。
四、数据过期策略
Redis提供了两种主要的数据过期策略:惰性删除和定期删除。
1、惰性删除:
优点:占用CPU资源少。
缺点:可能会导致内存中积累大量过期数据。
原理:只有当访问某个键时,才会检查该键是否过期,如果过期则删除。
2、定期删除:
原理:Redis会定期扫描内存中的键,删除过期的键。
配置示例:
hz 10 # 设置Redis的事件循环频率,单位为每秒
五、数据淘汰策略
Redis支持多种数据淘汰策略,可以通过maxmemory-policy配置。
| 策略 | 描述 | 适用场景 |
|---|---|---|
| noeviction | 不淘汰任何数据,当内存不足时返回错误 | 内存足够大,不需要淘汰数据 |
| allkeys-lru | 对所有键使用LRU(最近最少使用)算法淘汰 | 通用缓存场景 |
| volatile-lru | 对设置了过期时间的键使用LRU算法淘汰 | 热点数据缓存 |
| allkeys-random | 随机淘汰所有键 | 对数据一致性要求不高的场景 |
| volatile-random | 随机淘汰设置了过期时间的键 | 热点数据缓存 |
| allkeys-lfu | 对所有键使用LFU(最不经常使用)算法淘汰 | 访问频率差异较大的缓存 |
| volatile-lfu | 对设置了过期时间的键使用LFU算法淘汰 | 热点数据缓存 |
| volatile-ttl | 优先淘汰TTL较短的键 | 临时数据缓存 |
还有部分内容参考另一篇博文Redis面试问题详解2-CSDN博客
相关文章:
Redis面试问题缓存相关详解
Redis面试问题缓存相关详解 一、缓存三兄弟(穿透、击穿、雪崩) 1. 穿透 问题描述: 缓存穿透是指查询一个数据库中不存在的数据,由于缓存不会保存这样的数据,每次都会穿透到数据库,导致数据库压力增大。例…...
性能比拼: Elixir vs Go
本内容是对知名性能评测博主 Anton Putra Elixir vs Go (Golang) Performance (Latency - Throughput - Saturation - Availability) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 对比 Elixir 和 Go 简介 许多人长期以来一直要求我对比 Elixir 和 Go。在本视频…...
精益数据分析(6/126):深入理解精益分析的核心要点
精益数据分析(6/126):深入理解精益分析的核心要点 在创业和数据驱动的时代浪潮中,我们都在不断探索如何更好地利用数据推动业务发展。我希望通过和大家分享对《精益数据分析》的学习心得,一起在这个充满挑战和机遇的领…...
【Linux网络与网络编程】11.数据链路层mac帧协议ARP协议
前面在介绍网络层时我们提出来过一个问题:主机是怎么把数据交给路由器的?那里我们说这是由数据链路层来做的。 网络上的报文在物理结构上是以mac帧的形式流动的,但在逻辑上是以IP流动的,IP的流动是需要mac帧支持的。 数据链路层解…...
JAVA设计模式:注解+模板+接口
1.基础组件 1.1注解类控制代码执行启动、停止、顺序 /*** author : test* description : 数据同步注解* date : 2025/4/18*/ Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface SyncMeta {/*** 执行服务名称* return*/String name…...
Linux系统编程 day6 进程间通信mmap
父子共享的信息:文件描述符,mmap建立的共享映射区(MAP_SHARED) mmap父子间进程通信 var的时候 :读时共享,写时复制 父进程先创建映射区,指定共享MAP_SHARED权限 , fork创建子进程…...
【MySQL】MySQL建立索引不知道注意什么?
基本原则: 1.选择性原则: 选择高选择性的列建立索引(该列有大量不同的值) 2.适度原则:不是越多越好,每个索引都会增加写入开销 列选择注意事项: 1.常用查询条件列:WHERE字句中频繁使用的列 2.连接操作列…...
定制一款国密浏览器(9):SM4 对称加密算法
上一章介绍了 SM3 算法的移植要点,本章介绍对称加密算法 SM4 的移植要点。 SM4 算法相对 SM3 算法来说复杂一些,但还是比较简单的算法,详细算法说明参考《GMT 0002-2012 SM4分组密码算法》这份文档。铜锁开源项目的实现代码在 sm4.c 文件中,直接拿过来编译就可以。 但需要…...
Redis 的持久化机制(RDB, AOF)对微服务的数据一致性和恢复性有何影响?如何选择?
Redis 的持久化机制(RDB 和 AOF)对于保证 Redis 服务重启或崩溃后数据的恢复至关重要,这直接影响到依赖 Redis 的微服务的数据一致性和恢复能力。 1. RDB (Redis Database Backup) 机制: 在指定的时间间隔内,将 Redis 在内存中的…...
lottie深入玩法
A、json文件和图片资源分开 delete 是json资源名字 /res/lottie/delete_anim_images是图片资源文件夹路径 JSON 中引用的图片名,必须与实际图片文件名一致 B、json文件和图片资源分开,并且图片加载不固定 比如我有7张图片,分别命名1~7&…...
Android学习总结之算法篇七(图和矩阵)
有向图的深度优先搜索(DFS)和广度优先搜索(BFS)的示例,以此来模拟遍历 GC Root 引用链这种有向图结构: 一、深度优先搜索(DFS) import java.util.*;public class GraphDFS {privat…...
docker 大模型
使用 Docker 实现大模型的步骤指南 在今天的文章中,我们将指导刚入行的小白如何使用 Docker 来运行大模型。Docker 是一个开放源代码的平台,允许开发者自动化应用程序的部署、扩展和管理。通过将大模型放入 Docker 容器中,我们可以确保其在各…...
热门与冷门并存,25西电—电子工程学院(考研录取情况)
1、电子工程学院各个方向 2、电子工程学院近三年复试分数线对比 学长、学姐分析 由表可看出: 1、电子科学与技术25年相较于24年上升20分 2、信息与通信工程、控制科学与工程、新一代电子信息技术(专硕)25年相较于24年下降25分 3、25vs24推…...
Warcraft Logs [Classic] [WCL] BOSS ID query
Warcraft Logs [Classic] [WCL] BOSS ID query 所有副本BOSSID查询 https://wowpedia.fandom.com/wiki/DungeonEncounterID#Retail IDNameMapInstanceIDPatch227High Interrogator GerstahnBlackrock Depths230228Lord RoccorBlackrock Depths230229Houndmaster GrebmarBlackro…...
python录屏工具实现
python录屏工具实现 实现一 按Ctrl+Shift+8开始录制,按Ctrl+Shift+9结束录制,视频保存到“ d:\录屏视频”目录中。 先看用了哪些库 import cv2: 引入 OpenCV 库,这是一个开源计算机视觉库,用于图像和视频处理。在这个程序中,它用于创建视频文件、处理图像等。需要安装ope…...
架构师面试(三十一):IM 消息收发逻辑
问题 今天聊一下 IM 系统最核心的业务逻辑。 在上一篇短文《架构师面试(三十):IM 分层架构》中详细分析过,IM 水平分层架构包括:【入口网关层】、【业务逻辑层】、【路由层】和【数据访问层】;除此之外&a…...
基于若依框架前后端分离的项目部署
文章目录 单项目的部署项目目录后端打包上传前端打包上传配置nginx服务器打开防火墙完成 两个项目的部署两个项目介绍后端打包并上传前端打包并上传nginx配置服务器端口开放完成 腾讯云服务器 之 环境搭建 单项目的部署 项目目录 后端打包上传 查看端口号 在ruoyi-admin的appl…...
黑马Java基础笔记-1
JVM,JDK和JRE JDK是java的开发环境 JVM虚拟机:Java程序运行的地方 核心类库:Java已经写好的东西,我们可以直接用。 System.out.print中的这些方法就是核心库中的所包含的 开发工具: javac(编译工具)、java&…...
面向新一代扩展现实(XR)应用的物联网框架
中文标题: 面向新一代扩展现实(XR)应用的物联网框架 英文标题: Towards an IoT Framework for the New Generation of XR Applications 作者信息 Joo A. Dias,UNIDCOM - IADE,欧洲大学,里斯本&…...
pcl各模块
参考资料: https://github.com/Ewenwan/MVision/blob/master/PCL_APP/1_%E7%82%B9%E4%BA%91%E6%BB%A4%E6%B3%A2filter.md 点云库PCL各模块学习 语雀 各模块依赖关系: 模块: common pcl_common中主要是包含了PCL库常用的公共数据结构和方…...
Oracle Recovery Tools修复ORA-600 6101/kdxlin:psno out of range故障
数据库异常断电,然后启动异常,我接手该库,尝试recover恢复 SQL> recover database; ORA-10562: Error occurred while applying redo to data block (file# 2, block# 63710) ORA-10564: tablespace SYSAUX ORA-01110: ???????? 2: H:\TEMP\GDLISNET\SYSAUX01.DBF O…...
Python网络编程从入门到精通:Socket核心技术+TCP/UDP实战详解
引言 网络编程是构建现代分布式系统的核心能力,而Socket作为通信的基石,其重要性不言而喻。本文将从零开始,通过清晰的代码示例、原理剖析和对比分析,带你彻底掌握Python中的Socket编程技术,涵盖TCP可靠连接、UDP高效…...
2025MathorcupC题 音频文件的高质量读写与去噪优化 保姆级教程讲解|模型讲解
2025Mathorcup数学建模挑战赛(妈妈杯)C题保姆级分析完整思路代码数据教学 C题:音频文件的高质量读写与去噪优化 随着数字媒体技术的迅速发展,音频处理成为信息时代的关键技术之一。在日常生活中,从录音设备捕捉的原始…...
.net core web api 数据验证(DataAnnotations)
目录 一、什么是 DataAnnotations? 二、扩展验证逻辑(自定义验证器) 一、什么是 DataAnnotations? DataAnnotations 是一组特性(Attributes),用于在模型类上定义验证规则。主要用于属性级别的…...
【工具-Krillin AI】视频翻译、配音、语音克隆于一体的一站式视频多语言转换工具~
Krillin AI 是全能型音视频本地化与增强解决工具。这款简约而强大的工具,集音视频翻译、配音、语音克隆于一身,支持横竖屏格式输出,确保在所有主流平台(哔哩哔哩,小红书,抖音,视频号,…...
ICPR-2025 | 让机器人在未知环境中 “听懂” 指令精准导航!VLTNet:基于视觉语言推理的零样本目标导航
作者:Congcong Wen, Yisiyuan Huang, Hao Huang ,Yanjia Huang, Shuaihang Yuan, YuHao, HuiLin and Yi Fang 单位:纽约大学阿布扎比分校具身人工智能与机器人实验室,纽约大学阿布扎比分校人工智能与机器人中心,纽约大学坦登工程…...
Shiro-550 动调分析与密钥正确性判断
一、Shiro 简介 Apache Shiro是一个开源安全框架,用于构建 Java 应用程序,提供身份验证、授权、加密和会话管理等功能。 二、Shiro-550(CVE-2016-4437) 1、漏洞原理 Shiro 在用户登陆时提供可选项 RememberMe,若勾选…...
Python制作简易PDF查看工具PDFViewerV1.0查找功能优化
原文说明 为不破坏原文结构,因此功能优化不在原文中维护了。关于这款工具原文请通过下面链接访问。Python制作简易PDF查看工具PDFViewerV1.0 这款小工具基本功能已经可以作为一款文档浏览器使用,但还有一些美中不足的地方,本文将介绍对文本查…...
20250419将405的机芯由4LANE的LVDS OUT配置为8LANE的步骤
20250419将405的机芯由4LANE的LVDS OUT配置为8LANE的步骤 2025/4/19 15:38 查询格式YUV/RGB 81 09 04 24 60 FF 90 50 00 00 FF 查询辨率帧率 81 09 04 24 72 FF 90 50 01 03 FF 查询LVDS mode : Singel output/Dual output 81 09 04 24 74 FF 90 50 00 00 FF 配置405的机…...
从0开发一个unibest+vue3项目,使用vscode编辑器开发,总结vue2升vue3项目开始,小白前期遇到的问题
开头运行可看官网 链接: unibest官网 一:vscode中vue3代码显示报错标红波浪线 去查看扩展商店发现一些插件都弃用了,例如h5的插件以及vue老插件 解决办法:下载Vue - Official插件(注意:横杠两边是要加空格的ÿ…...
