缓存问题之面试问题汇总

面试题如何保证缓存的双写一致性

:缓存的双写一致性很难保证强一致,只能尽可能降低不一致的概率,确保最终一致。我们项目中采用的是Cache Aside模式。简单来说,就是在更新数据库之后删除缓存;在查询时先查询缓存,如果未命中则查询数据库并写入缓存。同时我们会给缓存设置过期时间作为兜底方案,如果真的出现了不一致的情况,也可以通过缓存过期来保证最终一致。

追问:为什么不采用延迟双删机制?

:延迟双删的第一次删除并没有实际意义,第二次采用延迟删除主要是解决数据库主从同步的延迟问题,我认为这是数据库主从的一致性问题,与缓存同步无关。既然主节点数据已经更新,Redis的缓存理应更新。而且延迟双删会增加缓存业务复杂度,也没能完全避免缓存一致性问题,投入回报比太低。

面试题如何解决缓存穿透问题

:缓存穿透也可以说是穿透攻击,具体来说是因为请求访问到了数据库不存在的值,这样缓存无法命中,必然访问数据库。如果高并发的访问这样的接口,会给数据库带来巨大压力。

我们项目中都是基于布隆过滤器来解决缓存穿透问题的,当缓存未命中时基于布隆过滤器判断数据是否存在。如果不存在则不去访问数据库。

当然,也可以使用缓存空值的方式解决,不过这种方案比较浪费内存。

面试题如何解决缓存雪崩问题

:缓存雪崩的常见原因有两个,第一是因为大量key同时过期。针对问这个题我们可以可以给缓存key设置不同的TTL值,避免key同时过期。

第二个原因是Redis宕机导致缓存不可用。针对这个问题我们可以利用集群提高Redis的可用性。也可以添加多级缓存,当Redis宕机时还有本地缓存可用。

面试题如何解决缓存击穿问题

:缓存击穿往往是由热点Key引起的,当热点Key过期时,大量请求涌入同时查询,发现缓存未命中都会去访问数据库,导致数据库压力激增。解决这个问题的主要思路就是避免多线程并发去重建缓存,因此方案有两种。

第一种是基于互斥锁,当发现缓存未命中时需要先获取互斥锁,再重建缓存,缓存重建完成释放锁。这样就可以保证缓存重建同一时刻只会有一个线程执行。不过这种做法会导致缓存重建时性能下降严重。

第二种是基于逻辑过期,也就是不给热点Key设置过期时间,而是给数据添加一个过期时间的字段。这样热点Key就不会过期,缓存中永远有数据。

查询到数据时基于其中的过期时间判断key是否过期,如果过期开启独立新线程异步的重建缓存,而查询请求先返回旧数据即可。当然,这个过程也要加互斥锁,但由于重建缓存是异步的,而且获取锁失败也无需等待,而是返回旧数据,这样性能几乎不受影响。

需要注意的是,无论是采用哪种方式,在获取互斥锁后一定要再次判断缓存是否命中,做dubbo check. 因为当你获取锁成功时,可能是在你之前有其它线程已经重建缓存了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值