缓存穿透:
概念
缓存穿透是指:数据在缓存(例如Redis)中没有,在数据库(例如Mysql)中也没有。而这时用户大量发起请求查询这条不存在的数据(例如:id = -1,或id很大),就会给数据库造成很大压力。
解决
1、接口层/业务层添加校验,拒绝id <= 0的请求访问;
2、请求通过缓存没获取到数据后,会从数据库中查询,若也没获取到,则将k-v中v的值设为null,存入缓存,但是过期时间需要设置的很短(1分钟内),避免影响正常请求;
缓存击穿:
概念
缓存击穿是指:缓存中没有数据,但数据库中有数据(一般是缓存时间到期),这时由于并发量特别高,同时读缓存没读到数据,又同时去数据库去获取数据,引起数据库压力瞬间增大,造成数据库压力过大。(并发查询同一条数据)
解决
1、设置数据永不过期;
2、加互斥锁,只允许一个请求去数据库获取,并写入缓存;
缓存雪崩:
概念
缓存雪崩是指:缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决
1、缓存数据的过期时间设置随机,防止出现同一时间大量数据过期现象;
2、如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中;
3、设置热点数据永远不过期;
思考:
场景:
大量请求访问缓存中不存在的数据(大部分是恶意攻击,数据库(mysql主键id自增)中也没有。少量为正常请求,Redis中没有,但是数据库中有),此种场景如何解决。
思考:
1、屏蔽到id <= 0的请求;
2、获取数据库中id最大的值,存入Redis,请求到达后,先判断id的值,是否超过Redis中存放的数据库中最大id的值,若超过,则直接返回错误提示。
注意:
Redis中存放的最大id的值,过期时间需要设短(防止出现过期时间内,mysql新增了数据,此时mysql的最大id的值,大于了Redis中存放的最大id的值。而正在这时候,有请求访问新增的这一条数据,则会出现访问不到的情况)
或者
mysql新增了数据,同步修改Redis中存放的mysql最大id的值。此种方法则不需要设置过期时间较短。
-----未完待续,欢迎交流-----