Springboot实战——黑马点评之缓存
Springboot黑马点评——缓存1 缓存初识与简朴素现
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240816171143796-1024830038.png
1.1 根据商铺id的缓存查询
基础缓存实现:
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240816171554556-973405159.png
考虑到有数据会同时存在于数据库和缓存中,所以:
Q:数据库和缓存的数据一致性题目?
A:三种缓存更新策略用来解决一致性题目
1.2 缓存更新策略的选择
[*]第一种:内存淘汰
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240820144740968-1428692173.png
[*]第二种:超时剔除
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240820144932850-1165430304.png
[*]第三种:主动更新(自行编码)
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240820145021467-531086666.png
1.2.1 主动更新策略:三种写缓存
一样平常主动更新策略最通用,主动更新策略又有三种写缓存的方式:
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240820145710274-983764226.png
一样平常使用第一种主动更新策略
即 调用者对缓存和数据库的一致性的操作编码 两者同时操作
同时我们需要考虑以下三点题目:
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240820150806883-1291730956.png
选择更新数据库删除缓存 避免更多的无效写操作
选择先操作数据库再删除缓存
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240820151512997-693040869.png
[*]不同场景对于缓存更新策略的选择
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240820151659190-672235711.png
2 缓存穿透与缓存击穿题目的解决方案
2.1 缓存穿透
常见的解决方法有两种:
[*]缓存空对象
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821113116449-1628461754.png
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821113326590-305779776.png
[*]布隆过滤
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821144750770-683797472.png
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821144920825-982458089.png
2.1.1 缓存穿透解决方案
像1.1那样读取数据:
先查Redis->Redis命中则转换存储格式返回
->Redis未命中则到数据库中查找
->数据库未命中则返回404数据不存在
->数据库命中则将数据转换存储格式写入Redis
(即下图的流程图)
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821145039655-582834852.png
存在缓存穿透的风险:若有恶意查询不存在数据的请求频繁插入,将会给数据库查询带来很大压力
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821145948456-1280211873.png
解决缓存穿透的方法:
[*]若从数据库查询为空,则将该空值存入Redis中
(设置有效时间为2分钟,以防止内存大量置空消耗)
[*]在Redis中置空的店肆在下一次用户查找时,非正常返回不存在错误信息而不是用户实体
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821150056585-376592369.png
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821151513050-137844008.png
2.2 缓存雪崩
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821152356657-566582149.png
2.3 缓存击穿
满意两个条件:高并发访问的热点数据/缓存重修业务很复杂
多个线程同时访问,而此时该业务的缓存数据已失效
则对数据库的持续查询造成很大负担且需要轮询等候
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821153224030-78862744.png
解决缓存击穿的两种方法:
[*]互斥锁
[*]逻辑逾期
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821153753334-395323345.png
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821153957703-690548664.png
2.4 实现缓存击穿解决思路
2.4.1 使用浅易互斥锁(redis中的SETNX方法)
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821155208897-1047657369.png
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821154928025-1321827756.png
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240821174411398-1546691850.png
2.4.2 使用逻辑逾期时间
逻辑锁:
条件条件:当前查询的对象属于热点key,例如属于当前活动或折扣商品,所以后台会在初始阶段将该热点数据存入Redis中(封装+逻辑逾期时间),请求大概率会直接命中
简朴来说就是 将逾期时间封装在键值中作为该对象的逻辑逾期时间(logic expiretime) 而存入Redis时不给该键值设置expiretime 对外显示为永世生效的键值
在命中该键值时->无论逾期时间是否到期->统一将当前(旧)数据返回给前端->
->如果逾期时间已到期->开启独立线程 重新从数据库中载入
->实验获取互斥锁(和互斥锁逻辑相同)
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240822160716971-1002042218.png
https://img2024.cnblogs.com/blog/3420577/202408/3420577-20240822170833118-1461647676.png
【知识点】:
开启独立线程 借助 java的线程池来实现:
线程池是一种常用的并发编程工具,它允许我们有效地管理和控制并发使命的实行。newFixedThreadPool方法接受一个整数参数,表现线程池中的线程数量。一旦线程池创建完成,我们就可以使用ExecutorService接口的方法来提交使命到线程池中实行。
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.submit(() -> {...提交至线程池中执行的内容})newFixedThreadPool默认使用无界队列(LinkedBlockingQueue)来保存等候实行的使命。这意味着如果线程池中的线程都在繁忙状态,新提交的使命将一直排队等候,而不会立即被拒绝。然而,这也大概导致队列中的使命数量无限制增长,从而消耗过多的内存资源。因此,在现实应用中,我们可以考虑使用有界队列来限制队列的最大容量,当队列满时,新提交的使命将被拒绝实行。
在应用程序结束时,我们需要确保正确地关闭线程池,以释放体系资源。ExecutorService接口提供了shutdown和shutdownNow两个方法来关闭线程池。
1)shutdown方法用于启动线程池的关闭序列。已经提交的使命将继续实行,但新的使命将不再接受。当所有使命都实行完毕后,线程池中的线程将主动终止。
2)shutdownNow方法实验停止所有正在实行的使命,并返回等候实行的使命列表。与shutdown方法不同,shutdownNow方法并不保证能够停止所有正在实行的使命,但它会实验中断正在实行的使命。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]