缓存穿透、缓存并发、缓存失效

一、缓存穿透

我们在项目中使用缓存通常都是APP先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回。这个时候如果我们查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB,这样缓存就失去了意义,在流量大时,可能DB就挂掉了。

这个问题其实经常遇到,只是没有引起足够的重视,在我想来,如果碰到这样的问题可以在封装的缓存SET和GET部分增加个步骤,如果查询一个KEY不存在,就已这个KEY为前缀设定一个标识KEY;以后再查询该KEY的时候,先查询标识KEY,如果标识KEY存在,就返回一个协定好的非FALSH或者NULL值,然后APP做相应的处理,这样缓存层就不会被穿透。当然这个验证KEY的失效时间不能太长。

 

二、缓存并发

有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

我现在的想法是再APP中对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。

 

三、缓存失效

引起这个问题的主要原因还是高并发的时候,平时我们设定一个缓存的过期时间时,可能有一些会设置5分钟啊,10分钟这些;并发很高时可能会出在某一个时间同时生成了很多的缓存,并且过期时间都一样,这个时候就可能引发一当过期时间到后,这些缓存同时失效,请求全部转发到DB,DB可能会压力过重。

前段时间我在网上也刚好看到了相关的文章,引用其中的一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

 

第二、第三个问题其实差不多,主要就时第二个问题时针对同一个缓存,第三个问题时针对很多缓存

### 缓存失效缓存穿透缓存击穿的概念及解决方案 #### 一、缓存失效 缓存失效指的是存储在缓存中的数据由于某种原因被移除或过期,导致后续请求无法命中缓存,进而需要从底层数据库重新获取数据的情况。如果大量的缓存同时失效,可能会引发瞬时的大规模数据库查询操作,给数据库带来巨大的压力。 为了缓解这一问题,可以采取以下措施: - 设置合理的缓存过期策略,例如引入随机化过期时间,避免大批量缓存同时到期[^1]。 - 使用分布式锁机制,在多个节点之间协调更新缓存的操作,减少重复写入的可能性。 - 实施限流降级策略,控制进入系统的流量,减轻数据库的压力。 #### 二、缓存穿透 缓存穿透是指某些恶意或者错误的请求试图访问根本不存在的数据,这些请求既未命中缓存也未命中数据库,最终使得每次请求都会直接到达数据库层,增加了不必要的负载。 以下是几种常见的解决办法: - **缓存空对象**:对于查不到的结果(即null),也可以将其短暂地保存至缓存中,设定较短的有效期限,从而阻止频繁尝试相同无意义的查找行为[^4]。 - 应用布隆过滤器技术提前拦截那些不可能存在的键值组合,降低无效查询的比例[^3]。 ```java // Java代码示例展示如何实现简单的缓存空对象逻辑 public class CacheService { private final Map<String, Object> cache = new HashMap<>(); public Object get(String key) { if (cache.containsKey(key)) { return cache.get(key); } else { // Simulate database fetch Object valueFromDb = fetchDataFromDatabase(key); if (valueFromDb != null) { cache.put(key, valueFromDb); } else { cache.put(key, "NULL_PLACEHOLDER"); // Store empty result temporarily. } return valueFromDb; } } private Object fetchDataFromDatabase(String key){ // Database fetching logic here... return null; // Example placeholder returning no data found case. } } ``` #### 三、缓存击穿 当特定高频次使用的单条记录突然消失于缓存之中,则会形成所谓的“热点key”缺失状况——短时间内大量并发请求涌入后台服务寻求该资源位置所在之处,此情形下同样容易致使DB承受不住如此密集型作业负荷而崩溃掉线。 对此类事件可考虑如下处理方式: - 预热热门数据项之前便预载入内存当中去;另外还可以借助互斥锁(Mutex Locks),确保同一时刻只有一个进程能够执行实际加载动作并同步其他等待者直至完成整个过程为止[^2]。 --- ### 总结说明 综上所述,无论是面对何种类型的缓存异常情况发生之时,我们都应该有针对性的设计预防以及应急响应计划出来加以应对处置才行得通顺合理科学高效!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值