的缓存异常处理,缓存雪崩( 二 )


比如(缓存过期时间 - 当前系统时间)小于 5 分钟,那么就刷新一次缓存,并且重置缓存过期时间;不过这个方法也有个致命的问题:如果一个数据,恰好在缓存失效前五分钟,一次访问都没有,那么就不会触发检查更新,当缓存失效后有大量请求访问,那么也会造成缓存击穿 。使用锁在缓存失效后,通过互斥锁或者队列,控制读数据库和写缓存的线程数量 。
第一种方法:整个方法是 synchronized 的,这样做虽然可以防止大量请求落到 DB 上,但是就算是缓存没有失效,需要从 DB 中查询数据也需要排队,无疑是降低了系统的吞吐量 。第二种方法:当缓存失效时,只对查询数据库的操作进行加锁,这样对于缓存没有失效的情况也非常友好,但是查询操作这里加锁,也只是会阻塞掉住其他调用,第一其他线程要等待,对调用方不友好,第二这些请求被阻塞的请求最终还是会落到 DB 上的 。
第三种方法:使用互斥锁,抢到锁的话读数据库并写入缓存,抢不到锁的话也不阻塞,而是直接去读缓存,如果缓存中依然读不到数据(抢到锁的可能还没有将缓存写入成功),就等一会再试试读缓存 。双缓存设置一级缓存和二级缓存,一级缓存过期时间短,二级缓存过期时间长或者不过期,一级缓存失效后访问二级缓存,同时刷新一级缓存和二级缓存 。
双缓存的方式,说白了就是不能将一级缓存和二级缓存中数据同时变成失效,当一级缓存失效后,有多个请求访问,彼此之间依然是竞争锁,抢到锁的线程查询数据库并刷新缓存,而其他没有抢到锁的线程,直接访问二级缓存(代码可以参考上文中的互斥锁),如图:我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注;关注我后,可私信发送数字【1】,获取学习资料 。
Java高并发下缓存问题的现象及本质原因是什么?

的缓存异常处理,缓存雪崩


缓存击穿缓存击穿是指缓存没有用户请求的数据但是数据库中有用户请求的数据,这时如果并发用户很多又无法通过缓存来得到数据只能从数据库取数据进而导致数据库压力瞬间增大,系统访问缓慢 。缓存雪崩缓存雪崩指的是同一时间有大量的缓存数据过期,这时候有大量的访问进而导致数据库压力剧增进而宕机 。缓存雪崩和缓存击穿的差别是,缓存雪崩指的是大量的数据到期,缓存击穿指的是单个缓存数据到期本质原因是系统在进行设计时对缓存体系设计不合理对于热点数据可以考虑设置为永不过期,通过手工的方式来处理热点数据对于缓存数据的过期时间设置为随机避免同一时间有大量的缓存数据失效可以考虑通过分布式的方式来配置缓存 。
如何解决Redis缓存雪崩、缓存穿透、缓存并发等问题?
的缓存异常处理,缓存雪崩


缓存穿透很多项目在使用Redis或其他缓存框架的时候,都是先查询缓存,查询不的话再查询数据库,查到之后再放到内存中;如果一个key值本身就不存在,那么每一次都会查询数据库,也就是常说的【缓存穿透】 。应对方法:如果在Redis中查询不到,并且查询数据库也没有结果,那么就将这个key写入到Redis中,value=http://www.codepub.com/shouji/peijian/空,并设置一个超时过期时间,例如五分钟,那么五分钟以内的对这个可以的所有查询就可以拦截下来,如果数据库有key对应的数据了,那么五分钟后Redis中的缓存过期,会访问数据库并加载缓存;但是如果被恶意攻击,每次请求的key都不相同且不存在,那么依然会穿透到数据库;布隆过滤器:将可能存在的数据Hash到一个足够大的bitmap上,它可以告诉你 “某个key一定不存在或者可能存在”,一个一定不存在的数据会被bitmap拦截 。

推荐阅读