缓存雪崩
假如一个系统,它在高峰期有每秒7000个请求,这时我们使用缓存抗住了这么高的请求。但如果在某个时间点缓存大量失效,或者缓存服务器挂掉了,那么这些请求就会直接作用在普通数据库中(如MySQL)。这么高的请求量,MySQL肯定抗不住,进而挂掉,数据库一挂,也会导致系统挂掉。
我们总结缓存雪崩触发的条件:
“”
高并发情况下
缓存服务器挂了
大量缓存集中失效
导致的后果就是:系统崩溃。
解决思路,对数据库增加限流排队访问,假设我们的数据库最多能抗住每秒2000的请求,那当我们请求数据库时,每秒的请求就需要控制在2000内,其余的请求就需要排队。同时我们要保证缓存服务器的高可用,就需要使用集群。另外我们也需要随机设置缓存key的失效时间,防止key在同一时间失效。
雪崩解决
关于限流操作,可以使用Spring Cloud相关的限流插件,这里我们使用Semaphore信号量模拟下限流操作。
在这里我们限定同时最多可以有5个请求访问,当我们有9个请求进来时,只有5个请求获取到可以访问的令牌,其余的4个请求在外面等待。当前面的访问结束时,会释放令牌,后面的4个请求就会去抢占这些令牌,这样反复执行。
这里我们就起到了限流的操作。
缓存穿透
假设存在一个key永远不会在缓存中存在,当黑客通过这个key去攻击系统,比如每秒发起了7000次攻击,那么无论如何都不会走缓存,攻击请求直接打在了数据库上,数据库肯定扛不住。导致了数据库崩溃,同时,系统也会崩溃。
穿透
我们的解决思路是:查询之前先判断目标数据是否存在,不存在的直接忽略。将流量拦截于缓存和数据库之前。
穿透解决
如上图,增加过滤器,在系统启动之前,我们需要将热点数据统一加载进入缓存中,当对热点数据访问时,会通过过滤器判断一一次,发现请求在缓存中不存在,就直接返回,不会经过数据库。
过滤器我们可以使用布隆过滤器,布隆过滤器的示例代码如下:
布隆过滤器主要就是将key通过hash算法计算出来的值分散到bitmap中,在bitmap中是以0和1存在的。
bitmap图
然而上面的算法存在缺陷:
“布隆过滤器并不能精准过滤。(布隆过滤器判定不存在,100%不存在,判断为存在,则可能不存在的。)理论上Hash计算值是有碰撞的(不同的内容hash计算出同样的值),导致不存在的元素可能 会被判断为存在
”
当然,布隆过滤器并非需要拦截所有的请求,只需要将缓存击穿控制在一定的量即可。
关于缓存穿透我们还可以采用以下方案:
“缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。
”
不过上面的方案有个缺陷:黑客可能同时拿多个不存在的key短时间访问,一样也会访问数据库,所以实际中需要按场景进行优化改造。
缓存雪崩和缓存穿透一般会在高并发形况下遇到,也是互联网大厂高频面试内容,掌握这些知识,相信你又进入了一个新天地。
往期推荐
扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料
回复"java" 获取java电子书;
回复"python"获取python电子书;
回复"算法"获取算法电子书;
回复"大数据"获取大数据电子书;
回复"spring"获取SpringBoot的学习视频。
回复"面试"获取一线大厂面试资料
回复"进阶之路"获取Java进阶之路的思维导图
回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)
回复"总结"获取Java后端面试经验总结PDF版
回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)
回复"并发导图"获取Java并发编程思维导图(xmind终极版)
另:点击【我的福利】有更多惊喜哦。