专栏首页Java后端技术栈cwnait面试被问:缓存击穿有什么解决方案

面试被问:缓存击穿有什么解决方案

前言

缓存(内存 or Memcached or Redis.....)在互联网项目中广泛应用,本篇博客将讨论下缓存击穿这一个话题,涵盖缓存击穿的现象、解决的思路、以及通过代码抽象方式来处理缓存击穿。

什么是缓存击穿?

上面的代码,是一个典型的写法:当查询的时候,先从Redis集群中取,如果没有,那么再从DB中查询并设置到Redis集群中。

注意,在实际开发中,我们一般在缓存中,存储的数据结构是JSON。(JDK提供的序列化方式效率稍微比JSON序列化低一些;而且JDK序列化非常严格,字段的增减,就很可能导致反序列失败,而JSON这方面兼容性较好)

假设从DB中查询需要2S,那么显然这段时间内过来的请求,在上述的代码下,会全部走DB查询,相当于缓存被直接穿透,这样的现象就称之为“缓存击穿”!

避免缓存击穿的思路分析

加synchronized?

如果synchronized加在方法上,使得查询请求都得排队,本来我们的本意是让并发查询走缓存。也就是现在synchronized的粒度太大了。

缩小synchronized的粒度?

上面代码,在缓存有数据时,让查询缓存的请求不必排队,减小了同步的粒度。但是,仍然没有解决缓存击穿的问题。

虽然,多个查询DB的请求进行排队,但是即便一个DB查询请求完成并设置到缓存中,其他查询DB的请求依然会继续查询DB!

synchronized+双重检查机制

通过synchronized+双重检查机制:

在同步块中,继续判断检查,保证不存在,才去查DB。

代码抽象

发现没有,其实我们处理缓存的代码,除了具体的查询DB逻辑外,其他都是模板化的。下面我们就来抽象下!

一个查询DB的接口:

既然查询具体的DB是由业务来决定的,那么暴露这个接口让业务去实现它。

一个模板:

Spring不是有很多Template类么?我们也可以通过这种思想对代码进行一个抽象,让外界来决定具体的业务实现,而把模板步骤写好。(有点类似AOP的概念)

改进后的代码:

从这里可以看出,我们并不关心缓存的数据从哪里加载,而是交给具体的使用方,而且使用方在使用时再也不必关注缓存击穿的问题,因为我们都给抽象了。

好了,到这里,关于缓存击穿就讨论到这里。

www.jianshu.com/p/93767dac6b56

在这金三银四的季节,栈长为大家准备了四面试宝典:

  • 《java面试宝典5.0》
  • 《Java(BAT)面试必备》
  • 《350道Java面试题:整理自100+公司》
  • 《资深java面试宝典-视频版》
  • 大量电子书籍

分别适用于初中级,中高级,以及资深级工程师的面试复习。

内容包含java基础、javaweb、各个性能优化、JVM、锁、高并发、反射、Spring原理、微服务、Zookeeper、数据库、数据结构、限流熔断降级等等。

本文分享自微信公众号 - Java后端技术栈(t-j20120622),作者:田老师

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 面试被问频率最高的几道Redis面试题

    Redis相关面试题确实很多,主要是因为知识点很多,但是面试的时候,不可能都问个遍,所以本文就来总结一下,面试被问频率最高的几道Redis的面试题。

    田维常
  • 吊打面试官系列:说说Integer缓存范围

    Integer是基本类型int的封装类。平时不管是入坑多年的小伙伴还在入坑路上的小伙伴,都应该知道的使用频率是相当高。

    田维常
  • 搞清楚一道关于Integer的面试题

    面试题3中的a=99相当于a=new Integer(99);重新给把一个新的对象引用地址给了a,所以a变了,最后输出是99。

    田维常
  • 对缓存击穿的一点思考前言什么是缓存击穿?避免缓存击穿的思路分析代码抽象

    缓存(内存 or Memcached or Redis.....)在互联网项目中广泛应用,本篇博客将讨论下缓存击穿这一个话题,涵盖缓存击穿的现象、解决的思路、以...

    用户2890438
  • 高并发架构技术|缓存失效、缓存穿透问题 PHP 代码解决

    缓存失效:   引起这个原因的主要因素是高并发下,我们一般设定一个缓存的过期时间时,可能有一些会设置5分钟啊,10分钟这些;并发很高时可能会出在某一个时间同时...

    猿哥
  • DotNET企业架构应用实践-系统架构与性能-在业务中实例使用缓存与缓存查询-附上视频

    回顾与说明      本文是DotNET企业架构应用实践系列中的一篇文章,同时也是一步一步教你使用AgileEAS.NET基础类库进行应用开发系统中的一篇文章,...

    魏琼东
  • 深入浅出mybatis之缓存机制

    提到缓存,我们都会不约而同地认识到这是提高系统性能的必要措施之一,特别是高命中率的缓存设置,将会大大提高系统的整体吞吐量。缓存的应用场景从小到在http会话中缓...

    2Simple
  • Guava CacheBuilder使用说明 原

    CacheBuilder是Guava用于创建LoadingCache、Cache实例的构建类。可以使用下面的方法来创建一个Cache实例。

    随风溜达的向日葵
  • 前端缓存那些事

    Cache-Control 比Expires比较要内涵,具备更多的属性,其中包括如下

    树酱
  • 高并发场景下,到底先更新缓存还是先更新数据库?

    在大型系统中,为了减少数据库压力通常会引入缓存机制,一旦引入缓存又很容易造成缓存和数据库数据不一致,导致用户看到的是旧数据。

    用户1516716

扫码关注云+社区

领取腾讯云代金券