回复“面试手册”,获取本站PDF版
回复“简历”,获取高质量简历模板
回复“加群”,加入程序员交流群
回复“电子书”,获取程序员类电子书
这是一个非常高频的面试题,也非常容易掌握,比较麻烦的是总是分不清这三个哪个是哪个
下图是一个正常的系统架构图,其中缓存的作用是减轻数据库的压力,提升系统的性能,无论是缓存雪崩、缓存击穿还是缓存穿透都是缓存失效了导致数据库压力过大。
缓存雪崩
什么是缓存雪崩?
缓存雪崩是指在某一个时刻出现大规模的缓存失效的情况,大量的请求直接打在数据库上面,可能会导致数据库宕机,如果这时重启数据库并不能解决根本问题,会再次造成缓存雪崩。
为什么会造成缓存雪崩?
一般来说,造成缓存雪崩主要有两种可能
- Redis宕机了
- 很多key采取了相同的过期时间
如何解决缓存雪崩?
- 为避免Redis宕机造成缓存雪崩,可以搭建Redis集群
- 尽量不要设置相同的过期时间,例如可以在原有的过期时间加上随机数
- 服务降级,当流量到达一定的阈值时,就直接返回“系统繁忙”之类的提示,防止过多的请求打在数据库上,这样虽然难用,但至少可以使用,避免直接把数据库搞挂
缓存击穿
什么是缓存击穿?
缓存雪崩是大规模的key失效,而缓存击穿是一个热点的Key,有大并发集中对其进行访问,突然间这个Key失效了,导致大并发全部打在数据库上,导致数据库压力剧增,这种现象就叫做缓存击穿。
比较经典的例子是商品秒杀时,大量的用户在抢某个商品时,商品的key突然过期失效了,所有请求都到数据库上了。
如何解决缓存击穿
- 虑热点key不设置过期时间,避免key过期失效
- 加锁,如果缓存失效的情况,只有拿到锁才可以查询数据库,降低了在同一时刻打在数据库上的请求,防止数据库宕机,不过这样会导致系统的性能变差。
缓存穿透
什么是缓存穿透
缓存穿透是指用户的请求没有经过缓存而直接请求到数据库上了,比如用户请求的key在Redis中不存在,或者用户恶意伪造大量不存在的key进行请求,都可以绕过缓存,导致数据库压力太大挂掉。
如何解决缓存穿透
- 参数校验,例如可以对用户id进行校验,直接拦截不合法的用户的请求
- 布隆过滤器,布隆过滤器可以判断这个key在不在数据库中,特点是如果判断这个key不在数据库中,那么这个key一定不在数据库中,如果判断这个key在数据库中,也不能保证这个key一定在数据库中。就是会有少数的漏网之鱼,造成这种现象的原因是因为布隆过滤器中使用了hash算法,对key进行hash时,不同的key的hash值一定不同,但相同的hash的值不能说明这两个key相同。下面简单介绍下布隆过滤器,这个面试也常问。
布隆过滤器底层使用bit数组存储数据,该数组中的元素默认值是0。
布隆过滤器第一次初始化的时候,会把数据库中所有已存在的key,经过一系列的hash算法计算,算出每个key的位置,并将该位置的值置为1,为了减少哈希冲突的影响,可以对每个key进行多次hash计算,如下图
现在,用户所有的请求都要经过布隆过滤器过滤一遍,如果只有用户请求的key的hash值都是1才可以通过,否则直接拦截,如下图
那使用布隆过滤器就可以完美解决问题了吗?当然没有,使用布隆过滤器解决缓存穿透问题的同时也带来了一些其他问题:
布隆过滤器存在误判的情况
布隆过滤器不支持删除,因为布隆过滤器中存的1可能涉及多个key,直接删除可能会影响到其他key,比如上图第四个位置的1就涉及两个key
如果数据库中数据更新同步到布隆过滤器时失败,布隆过滤器则会将本来正常的请求拦截住,这是非常致命的
先来看第一个问题,前面已经解释过了布隆过滤器存在误判的原因,就是不同的key的hash值可能相同。因为每个key要经过多次hash计算,恰好每次hash计算都和其他key的hash值相同的概率是很低的,有少数的漏网之鱼通过了布隆过滤器也不要紧,所以第一个问题不必担心。如果想要减少hash冲突导致的误判,可以适当增加key的hash次数。
第二个问题可以在布隆过滤器中以计数的方式存储,如下图
上图中位置4被key1和key2的hash值覆盖,则为2,如果删除key2,则为下图
第三个问题出现概率不大,如果这种问题对业务影响很大,可以考虑其他解决缓存穿透的方法。
本站链接:https://www.mianshi.online,如需勘误或投稿,请联系微信:lurenzhang888
点击面试手册,获取本站面试手册PDF完整版