缓存击穿的解决方案
【摘要】 缓存击穿在微服务架构中,Redis等缓存系统被广泛用于提高系统的响应速度和减轻数据库的压力。通过将热点数据存储在缓存中,系统可以直接从缓存中获取数据,而无需每次都查询数据库,从而大大提高了系统的性能。然而,在使用缓存的过程中,也会遇到一些问题,其中之一就是缓存击穿问题。什么是缓存击穿缓存击穿是指当缓存中没有某个热点数据的缓存时(一种情况是缓存时间到期,另一种是大量请求集中在程序某一处判定为缓...
缓存击穿
在微服务架构中,Redis等缓存系统被广泛用于提高系统的响应速度和减轻数据库的压力。通过将热点数据存储在缓存中,系统可以直接从缓存中获取数据,而无需每次都查询数据库,从而大大提高了系统的性能。然而,在使用缓存的过程中,也会遇到一些问题,其中之一就是缓存击穿问题。
什么是缓存击穿
缓存击穿是指当缓存中没有某个热点数据的缓存时(一种情况是缓存时间到期,另一种是大量请求集中在程序某一处判定为缓存不能存在),而此时恰好有大量的并发请求请求这个数据,这些请求都会直接打到数据库上,造成数据库短时间内承受大量请求而崩掉。
缓存击穿的原因
- 缓存失效:当缓存中的数据因为过期时间到达而被删除,而新的缓存数据还没有被加载进来时,如果此时有大量的请求到来,这些请求都会直接打到数据库上,造成缓存击穿。
- 缓存未命中:由于某些原因(如数据更新、缓存被误删等),缓存中不存在某个数据的缓存,当大量请求同时访问这个数据时,它们都会穿透缓存直接访问数据库。
- 对于第一次请求:当第一次请求时,会判断缓存中没有存在这个数据,请求就会直接落到数据库上,当瞬间有大量的请求时,很有可能都会判断缓存中没有数据,直接全都打到了数据库层面上(开头举例就是此情况)
缓存击穿的解决方案
- 设置热点数据永远不过期:这是一种简单直接的解决方案,但是会导致缓存中的数据无法实时更新,可能引发数据不一致的问题
- 分布式锁:当缓存失效时,不是立即去加载数据库数据,而是先使用分布式锁去获取加载数据的权限,当获取到权限后,再去加载数据到缓存。这样,在第一个请求去加载数据时,其他并发请求则需要等待,第一个请求将数据加载到缓存后,直接释放分布式锁,此时其他请求就能够从缓存中获取数据,而不需要再去查询数据库
解决方案的分析
- 第一种方案数据不过期肯定是不行的,就算只存放热点数据,但是也会随着数据量越来越大的情况下,redis的承受压力也会越来越大
- 第二种使用分布式锁让请求进行串行化,确实可以解决缓存击穿的问题,我们来写一段代码实现使用分布式锁的方案
使用分布式锁
public String getDataV2(String id){
RedisTemplate<String,String> redisTemplate = redisCache.getInstance();
String cachedValue = redisTemplate.opsForValue().get(id);
if (StringUtil.isEmpty(cachedValue)) {
//分布式锁
RLock lock = serviceLockTool.getLock(LockType.Reentrant, id);
lock.lock();
try {
Program program = programMapper.selectById(id);
if (Objects.nonNull(program)) {
redisTemplate.opsForValue().set(id,JSON.toJSONString(program));
cachedValue = JSON.toJSONString(program);
}
} finally {
lock.unlock();
}
}
return cachedValue;
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)