建议收藏,下次面试被问缓存,如果还答不上,面试前先看看!
缓存的意义
1:缓存的数据存在内存,内存中的数据操作,性能比数据库、磁盘高。
2:缓存资源的消耗相比数据库资源的消耗更低。基于提高应用性能的目的,使用缓存提升了数据处理的性能,降低数据存储的性能消耗,提高了数据访问的响应。
缓存雪崩
问题产生:
对于高并发项目,同一时间可能有很多请求过来,对于相同key规则的缓存,在这一时间点同时缓存了多个key。当大量的缓存key设置的过期时间都是同一个时间点,那么当到达这个时间点时,这批大量的缓存key失效,导致请求全部落地到数据库,造成数据库瞬间并发请求提高,带来缓存雪崩问题。
解决方案:
1:过期时间添加随机值,将相同过期时间点概率降低。(弊端:缓存失效时间不能准确的管理)
2:缓存不设置过期时间,通过更新操作更新缓存。(弊端:更新失败时存在缓存一致性问题)
缓存穿透
问题产生:
对于请求的key,在缓存及db中都不存在,数据库查询不存在,也不进行缓存设置,导致每次请求都落地到数据库。如果是恶意的请求,将造成数据库压力过大。例如:业务id是数据库自增的,使用id为-1的请求参,如果没做检验,那么每次请求都会查询数据库,而且数据不存在。
解决方案:
1:将不存在的key也缓存,设置value为特定业务值及合适的过期时间。那么当不存在的key的再次请求过来时,查询缓存,并且在过期时间内不会落地数据库。(弊端:当数据库出现新的id,且之前缓存已经被设置为空值,那么过期时间内无法访问新增的数据)
2:布隆过滤器,将所有可能存在的id存储在一个bitmap,请求前先经过过滤器判断是否存在。(弊端:存在误判的可能)
缓存击穿
问题产生:
对于某个热点key,每秒并发很高,在key失效的时间点,瞬间并发请求同时查询数据库,导致数据库压力瞬时暴涨。这里跟雪崩的区别是,这里指单个key的失效,因为是高并发导致还没来得及缓存,就有大量请求落地到数据库。而雪崩是同时有多个key失效,这些key可能不是热点key并不一定也有击穿问题。如果这样的热点key很多,而且存在跟缓存雪崩一样问题的情况,数据库无疑压力更大。
解决方案:
1:热点key不设置过期时间,通过更新操作同步,将请求完全落地到缓存。(弊端:更新失败带来的一致性问题)
2:通过锁机制,只允许一个请求查库,同时可以考虑使用缓存降级,获得锁失败的进程查询降级的缓存,即二级缓存机制。(弊端:互斥锁带来的性能问题,导致其他线程在等待)
ONE MORE THING
缓存问题也有使用分布式redis与本地缓存结合,视业务情况使用即可。
另外一点就是缓存一致性的问题,是先删除缓存再更新缓存,还是先更新数据再删除缓存?平时项目里是怎么实现的呢?
我们下次再聊,喜欢的点点关注,留意更新。