redis之缓存击穿

67 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情

前言

在前几天的文章里面我们讲述了缓存穿透和缓存雪崩。所以今天就来讲下这缓存的最后一部分——缓存击穿。

什么是缓存击穿

这个问题出现的主要场景是一个可能会被大量使用的key突然失效了,失效之后因为是热点key所以在下一个瞬间,大量的请求(几乎是同一时间还没来得及缓存)直接到达持久层,给数据库造成了巨大的压力。这就像缓存层直接被干穿了一样,所以就叫缓存击穿。

解决方法

互斥锁

我们首先从字面意思上理解一下这个锁的意思,互斥就是互相排斥的意思。上面的热点key不存在之后,有许多的线程直接去到了持久层导致持久层的压力过大。所以我们现在是用互斥锁,使大量的线程互相排斥,不能同一时候给持久层压力。这样是不是就避免了缓存击穿问题。

具体案例

像如果是只有一台服务器我们可以使用Java的关键词,将获取到的key的名称作为锁,然后进行单线程操作。

synchronized ()

但如果是多台服务器的话,这个关键词就没有什么作用了。至于解决方法就是redis的分布式锁(后面文章详细讲解)。

优缺点

对于互斥锁来说,因为是单线程操作,实现起来比较简单,而且数据的一致性几乎不会出现问题。但是也是因为是单线程操作,会比较慢,性能这方面就无法达到要求。而且会有可能出现死锁的问题,就是在某些情况下,拿到锁的线程在完成了任务之后,发生了异常,无法正常释放锁,这样其他线程就一直在外面。所以我们还要定时的释放锁,虽然还是可能发生,但是一段时间之后就结束了。