Part01前言在高并发系统架构中,大量网络请求的并发处理导致数据库的I/O消耗巨大。为了快速读取数据,减少网络请求延迟,缓解数据库压力,因此在软件开发中引入了缓存技术。但是在使用缓存的过程中,一些特殊情况也会导致缓存失效。缓存失效常见的情况有三种:缓存穿透、缓存击穿、缓存雪崩。Part02缓存失效三种情况引入缓存(以Redis缓存为例)可以减少对数据库的请求次数,提高查询效率,提高系统性能。大致流程是:应用发起请求后,首先检查缓存中是否存在需要的数据。如果缓存中存在,则直接返回数据。如果缓存中不存在需要的数据,则需要查询数据库。数据一方面存储在缓存中,另一方面返回查询结果。如果数据库中不存在,则返回空或错误。图1缓存使用流程图——缓存穿透缓存穿透(CachePenetration)是指查询一个一定不存在的数据,即用户访问的数据既不在缓存中,也不在数据库中。由于无法在缓存中查询到数据,因此请求会查询数据库。但是数据库中不存在数据,不会写入缓存。这样一来,在查询数据的时候,每次都要查询数据库,给数据库造成了压力。.-CacheAvalanche缓存雪崩(CacheAvalanche)是指大量的缓存数据在某一时刻超过了缓存的过期时间,同时失效,导致高并发请求同时访问数据库,从而导致数据库压力过大,导致系统崩溃。这适用于多个缓存数据。-缓存击穿缓存击穿(CacheBreakdown)是指在缓存失效的瞬间,有大量的请求去查询同一个缓存数据。并发会直接去请求数据库,造成数据库压力成倍增加。这是针对缓存数据的。Part03Solution缓存穿透的解决方案:1.第一种方案是使用Bloomfilters进行数据拦截。这也是缓存崩溃的常见解决方案。在写入数据时,使用Bloomfilter标记数据的key。当带有datakey的请求过来时,首先使用Bloomfilter验证key是否存在。如果存在,则进入缓存或数据库进行查询。2.第二个选项是缓存空值。当无法在数据库中查询到数据时,将其缓存为空值或默认值。这时需要注意的是,它的缓存过期时间不能太长。一般设置在5分钟以内。当数据库写入或更新此键的新数据时,必须同时更新缓存以确保数据一致性。缓存雪崩的解决方法:1、一般在key的过期时间后加上一个随机数,让过期时间分散开来,平均失效key,降低缓存时间过期的重复率。2、使用锁或者队列来保证单线程写缓存,但是这种方案会影响并发量。当多个请求到来时,只有一个在执行正常操作,其他请求会处于等待状态,影响程序性能。,不推荐。3.使用缓存标签,这是一个更好的解决方案。判断tag是否过期,过期请求会在数据库中进行,缓存数据的过期时间要设置的比缓存的tag长。这样,当一个请求去数据库的时候,其他请求拿到的是上次的Cache数据。缓存崩溃的解决方案:1.使用互斥锁。当cachekey过期时,多个请求到来时只允许一个请求查询数据库建立缓存。其他请求等待请求的执行完成,然后重新从缓存中启动。检索数据。2、对于访问量比较大的数据,即热点数据,不设置缓存过期时间,后台异步更新缓存,适用于对缓存一致性要求不严格的场景。
