1 缓存穿透

定义: 缓存穿透,是指查询一个数据库中一定不存在的数据。

查询流程:

正常的使用 Redis 缓存的流程:

1、数据查询首先进行缓存查询

2、如果数据存在,则直接返回数据

3、如果数据不存在,则对数据库进行查询,并把查询到的数据放进缓存中

4、如果数据库查询为空,则不放进缓存

举例:

假设数据表中主键是自增产生的,所有的主键值都大于0。此时如果用户传入的参数为 -1,会是怎么样?这个 -1,就是一定不存在的对象。程序就会每次都去查询数据库,而每次查询都是空,每次又都不会进行缓存。假如有人恶意攻击,就可以利用这个漏洞,对数据库造成压力,甚至压垮数据库。

解决方案:

如果从数据库查询的对象为空,也放入缓存,key 为用户提交过来的主键值,value 为 null,只是设定的缓存过期时间较短,比如设置为 60 秒。这样下次用户再根据这个 key 查询 redis 缓存就可以查询到值了(值为null),从而保护我们的数据库免遭攻击。

2 缓存雪崩

定义: 缓存雪崩,是指在某一个时间段,缓存集中过期失效。在缓存集中失效的这个时间段对数据的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。

解决方案:

为了避免缓存雪崩的发生,我们可以将缓存的数据设置不同的失效时间,这样就可以避免缓存数据在某个时间段集中失效。例如对于某购物网站中热门的商品数据(访问频率高的数据)可以缓存的时间长一些,对于冷门的商品数据可以缓存的时间段一些。甚至对于一些特别热门的商品数据可以设置永不过期。

3 缓存击穿

定义: 缓存击穿,是指一个 key 非常热点(例如双十一期间进行抢购的商品数据),在不停的扛着大并发,大并发集中对这一个点进行访问,当这个 key 在失效的瞬间,持续的大并发就穿破缓存,直接请求到数据库上,就像在一个屏障上凿开了一个洞。

解决方案:

可以将这些热点数据设置永不过期,就可以解决缓存击穿的问题了。