- 被面试官问得一愣一愣的,虽然offer没拿到,面试经验还是要记录下来
- 借鉴了这个大哥的博客 https://blog.csdn.net/qq_35190492/article/details/102889333
- 再总结成为自己的话,记录下来一方面加深印象,另一方面以后好看
一、Redis雪崩
举个栗子:redis一般都会设置过期时间的,如果在秒杀开始的时候,这时候大量的都Key过期了,大量的用户涌入进来直接请求到DB上,DB肯定扛不住直接就会挂掉,此时,用户一直请求,重启的数据库,立马又被新的流量给打死了,这就是缓存雪崩。
面试的时候加点料:redis的key同一时间大面积失效,那一瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,可能都已经失去大批量的用户了。
对应的解决办法:
- 在批量往Redis存数据的时候,把每个Key的失效时间都加个随值,这样可以保证数据不会在同一时间大面积失效,造成大量的请求落到数据库上
- 如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题
- 请求量大的Key数据永远不过期,有更新的话手动更新一下缓存
二、缓存击穿,和雪崩的区别
- 缓存击穿和缓存雪崩有点相似的地方,缓存雪崩是因为大面积的缓存失效,打崩了DB
- 缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。
对应的解决办法:
缓存击穿的话,设置热点数据永远不过期,在更新的时候手动更新
三、缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,这个时候的请求都是落到了数据库上,这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。
面试的时候加点料:数据库id都是大于0的,我一直用小于0的参数去请求你,每次都能绕开Redis直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了。
对应的解决办法:
- 接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return
- 从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null,但是时间短一点 2-30秒这样,不然会导致正常的时候这个Key值也不能访问
- 这种情况一般都是攻击者,单位秒内发起过多请求,就直接在Nginx给他挡在外面,用户是不会在单位秒内发起这么多请求的