没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
内容概要:本文从基本概念出发,全面解析缓存的作用及原理,涵盖缓存的基本分类及其在不同应用场景中的使用策略。特别探讨分布式缓存的三大经典算法(LRU, LFU, FIFO),并给出具体实现案例——使用LinkedHashMap实现LRU缓存。接着,文章详细阐述常见的分布式缓存问题,如缓存穿透、雪崩和击穿,并提供详细的解决方案和技术手段。此外,介绍了各种类型的缓存工具和框架,包括但不限于Guava LocalCache、Redis、MemCache等。 适合人群:后端开发者、系统架构师,尤其是有一定经验的技术人员,旨在深入掌握缓存机制与故障排除技巧。 使用场景及目标:在高性能Web应用和服务中高效管理和利用缓存资源,确保系统稳定运行的同时优化性能指标。目标是通过实施文中所述策略和技巧,解决实际工作中遇到的各种缓存相关问题,提高开发效率和产品质量。 其他说明:建议读者在理解理论基础上实践相关代码实现,同时参考推荐的学习材料加深理解。
资源推荐
资源详情
资源评论


















【缓存】面试题
以下面试题,基于网络整理,和自己编辑。具体参考的文章,会在文末给出所有的链接。
如果胖友有自己的疑问,欢迎在星球提问,我们一起整理吊吊的【缓存】面试题的大保健。
而题目的难度,尽量按照从容易到困难的顺序,逐步下去。
另外,本文只分享通用的【缓存】的面试题,关于 Redis、MemCache 会单独分享。
再另外,本文【缓存】指的更多的是分布式缓存服务,而不是 HTTP 缓存等等。
什么是缓存?
:这个问题,理解即可。
缓存,就是数据交换的缓冲区,针对服务对象的不同(本质就是不同的硬件)都可以构建缓存。
目的是,把读写速度慢的介质的数据保存在读写速度快的介质中,从而提高读写速度,减少时间消耗。例如:
CPU 高速缓存 :高速缓存的读写速度远高于内存。
CPU 读数据时,如果在高速缓存中找到所需数据,就不需要读内存
CPU 写数据时,先写到高速缓存,再回写到内存。
磁盘缓存:磁盘缓存其实就把常用的磁盘数据保存在内存中,内存读写速度也是远高于磁盘的。
读数据,时从内存读取。
写数据时,可先写到内存,定时或定量回写到磁盘,或者是同步回写。
为什么要用缓存?
正如在 「什么是缓存?」 问题中所看到的,使用缓存的目的,就是提升读写性能。而实际业务场景下,更多的是
为了提升读性能,带来更好的性能,更高的并发量。
日常业务中,我们使用比较多的数据库是 MySQL ,缓存是 Redis 。一起来看看,阿里云提供的性能规格:
Redis 性能规格,https://help.aliyun.com/document_detail/26350.html 。打底 8W QPS ,最高可达千万
QPS 。
MySQL 性能规格 https://help.aliyun.com/document_detail/53637.html 。打底 1.4K QPS ,最高 7W QPS
。
如此一比较,Redis 比 MySQL 的读写性能好很多。那么,我们将 MySQL 的热点数据,缓存到 Redis 中,提升读
取性能,也减小 MySQL 的读取压力。例如说:
论坛帖子的访问频率比较高,且要实时更新阅读量,使用 Redis 记录帖子的阅读量,可以提升性能和并发。
商品信息,数据更新的频率不高,但是读取的频率很高,特别是热门商品。
请说说有哪些缓存算法?是否能手写一下 LRU 代码的实现?
🦅 缓存算法

缓存算法,比较常见的是三种:
LRU(least recently used ,最近最少使用)
LFU(Least Frequently used ,最不经常使用)
FIFO(first in first out ,先进先出)
完整的话,胖友可以看看 《缓存、缓存算法和缓存框架简介》 的 「缓存算法」 部分。
🦅 手写 LRU 代码的实现
手写 LRU 代码的实现,有多种方式。其中,最简单的是基于 LinkedHashMap 来实现,代码如下:
其它更复杂,更能体现个人编码能力的 LRU 实现方式,可以看看如下两篇文章:
《动手实现一个 LRU Cache》
《缓存、缓存算法和缓存框架简介》 文末,并且还提供了 FIFO、LFU 的代码实现。
常见的常见的缓存工具和框架有哪些?
在 Java 后端开发中,常见的缓存工具和框架列举如下:
本地缓存:Guava LocalCache、Ehcache、Caffeine 。
Ehcache 的功能更加丰富,Caffeine 的性能要比 Guava LocalCache 好。
分布式缓存:Redis、MemCache、Tair 。
Redis 最为主流和常用。
用了缓存之后,有哪些常见问题?
常见的问题,可列举如下:
class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int CACHE_SIZE;
/**
* 传递进来最多能缓存多少数据
*
* @param cacheSize 缓存大小
*/
public LRUCache(int cacheSize) {
// true 表示让 LinkedHashMap 按照访问顺序来进行排序,最近访问的放在头部,最老访问的放在尾
部。
super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true);
CACHE_SIZE = cacheSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
// 当 map 中的数据量大于指定的缓存个数的时候,就自动删除最老的数据。
return size() > CACHE_SIZE;
}
}

缓存何时写入?并且写时如何避免并发重复写入?
缓存如何失效?
缓存和 DB 的一致性如何保证?
如何避免缓存穿透的问题?
如何避免缓存击穿的问题?
如果避免缓存雪崩的问题?
:重点可以去“记”加粗的五个词。
下面,我们会对每个问题,逐步解析。
当查询缓存报错,怎么提高可用性?
缓存可以极大的提高查询性能,但是缓存数据丢失和缓存不可用不能影响应用的正常工作。
因此,一般情况下,如果缓存出现异常,需要手动捕获这个异常,并且记录日志,并且从数据库查询数据返回给用
户,而不应该导致业务不可用。
当然,这样做可能会带来缓存雪崩的问题。具体怎么解决,可以看看本文 「如何避免缓存”雪崩”的问题?」 问题。
如果避免缓存”穿透”的问题?
🦅 缓存穿透
缓存穿透,是指查询一个一定不存在的数据,由于缓存是不命中时被动写(
被
动
写
,
指
的
是
从
DB
查
询
到
数据
,
则
更新
到
缓
存
中
)的,并且处于容错考虑,如果从 DB 查不到数据则不写入缓存,这将导致这个不存在的数据每次请
求都要到 DB 去查询,失去了缓存的意义。
在流量大时,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击我们的应用,这就是漏洞。如下图:
剩余11页未读,继续阅读
资源评论


bug搬运工
- 粉丝: 196
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 【时间序列预测】MATLAB实现基于TCN-GRU-ABKDE时间卷积门控循环单元(TCN-GRU)结合自适应带宽核密度估计(ABKDE)进行多变量回归区间预测的详细项目实例(含模型描述及部分示例代码
- 【多变量时间序列预测】MATLAB实现基于VMD-MLR-NGO-BiLSTM变分模态分解(VMD)结合多元线性回归(MLR)和北方苍鹰优化算法(NGO)及双向长短期记忆网络(BiLSTM)进行多变量
- XSS漏洞 ,自动化漏洞扫描
- WPF自定义窗口标题、皮肤
- 基于Spring Boot、MyBatis-Plus、MySQL与微信小程序的简易增删改查功能实现
- C# WinForms工业相机+本地图像 通过YoloV8深度学习模型实现各类垃圾的分类检测 源码
- JSSS-Find js fuzz ,js 敏感信息自动提取
- 个人工作室网站源码 工作室官网PHP源码typecho主题.zip
- 成果转化智能体:赋能高校科研生态的智慧引擎.docx
- 成果转化智能体:赋能技术经理人全链条服务.docx
- 成果转化新引擎:构建高校创新生态价值网络.docx
- 成果转化智能体:赋能技术经理人全链条服务生态.docx
- 成果转化智能体:赋能技术经理人新生态.docx
- 成果转化智能体:赋能科技创新全链条服务生态.docx
- 成果转化智能体:赋能全链条服务生态_1.docx
- 成果转化智能体:赋能全链条服务生态.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
