一、缓存击穿
1.概念
当缓存中的某一个热key过期时,这时候有大量的并发请求访问这个key。但是这个key已经过期了,这时候这些请求会击穿缓存去直接请求到数据库,造成数据库的超负载。总结,这种情况是缓存中没有数据,但是数据库中有数据。就像在一道屏障上凿开了一个口子,突破了我们的缓存服务器直接请求到数据库,故名为缓存击穿。
2.解决方案
- 设置热点key永不过期。
- 异步定时更新:如果某一个热点key的过期时间是2小时,那么我们在1小时58分的时候通过定时任务去更新这个key,并重新设置定时时间为2小时。
- 互斥锁:如果从缓存中查询到这个key的值为空时,不是立即去查询数据库,而是先加锁。加锁后再去查询数据库,然后设置缓存释放锁。这样其他线程也在请求该key的时候,发现获取锁失败则先会阻塞。
二、缓存穿透
1.概念
当我们查询一个key时缓存中没有数据,数据库中也没有符合条件的数据。导致每次业务请求都会绕过缓存服务器直接查询数据库,失去了缓存应有的作用。如果有恶意请求的话,会有大量请求落在数据库上,造成数据库压力过大,影响正常的业务。总结,这种情况是在缓存中没有数据,在数据库中也没有数据。
2.解决方案
- 缓存空值:对于这些在缓存中没有值,数据库中也没有值的key,我们可以在缓存中设置值为null并设置过期时间。这样再有请求查询这个key的时候,直接返回null即可,不需要再查一次数据库。
- 布隆过滤器:布隆过滤器是一种比较巧妙的概率性数据结构,它占用内存少、效率高,可以告诉你数据一定不存在或者可能存在。对于缓存穿透,我们可以将查询的数据条件都hash到一个布隆过滤器中,当有请求来的时候会先被布隆过滤器拦截。一定不存在的数据就会直接返回空值,从而避免了再次请求数据库。
三、缓存雪崩
1.概念
当大量的key同时过期或者缓存服务器宕机时,这时候所有的请求过来都会直接打在数据库上。造成数据库超负荷运行,甚至造成数据库宕机。总结:这种情况是缓存中大量的key同时过期或缓存服务器宕机。
2.解决方案
- 设置不同的过期时间:为了避免大量的key在同一时间过期,我们可以把不同的key设置为不同的过期时间。并且部分热点key,通过定时任务刷新过期时间。
- 集群部署:在缓存雪崩问题的解决上,最有效的方式就是缓存集群部署。使用集群部署可以防止单点故障的问题。