当前位置: 首页 > 后端技术 > Java

你遇到过缓存雪崩、缓存穿透、缓存击穿么

时间:2023-04-01 21:49:29 Java

你遇到过缓存雪崩、缓存穿透、缓存击穿吗?Redis现在已经成为了缓存的“专业用户”。许多系统缓存使用Redis。Redis中的缓存雪崩、击穿、穿透也成为老生常谈的问题。今天小编就带大家梳理一下出现这些问题的原因和解决方法。缓存雪崩的原因缓存雪崩的原因是当某个时刻发生大规模的缓存故障时,比如你的缓存服务宕机了,会有大量的请求进来,直接发往数据库,这可能会导致整个系统出现故障。碰撞。解决方案设置不同的过期时间比较简单易懂。解决方法是给缓存的过期时间设置一个1-5分钟的随机值,这样每次缓存过期时间的重复率就会降低,避免缓存过期。大量到期的时刻。设置热键永不过期设置热键永不过期或使用异步线程刷新即将过期的热键的过期时间。限流,使用锁或者队列,避免大量请求同时崩溃。通过加锁或者队列的方式来保证缓存的单线程写入,可以防止大量缓存失效后短时间内请求打到DB。缺点是降低了系统的吞吐率。Hierarchicalcache缓存击穿缓存击穿的原因类似于缓存雪崩。缓存雪崩是大部分键失效,缓存击穿热点键失效。如果设置了过期时间的key在某个时间有大并发的直接请求,恰好此时过期,请求会直接打到DB,而不会读取缓存中的数据,导致服务崩溃。解决锁更新比如请求查询A,发现不在缓存中,锁定A的key,同时去数据库查询数据,写入缓存,然后返回给用户,以便后续请求可以从缓存中获取数据。为热键设置永无止境的截止日期,使用锁或队列,避免同时出现大量请求而崩溃。DB缓存穿透的根本原因是请求了缓存中不存在的key,导致每次请求都命中DB。通常为了系统的容错性,我们会在查询后有结果的情况下写入缓存,以便下次请求时直接从缓存中读取数据。那么当请求的id在数据库中存在时,比如数据库中主键使用的自增id,请求的是-1,那么这会导致数据在缓存中不存在,会从中进行校验每次请求的数据库,也就是失去了缓存的意义,当并发量大的时候,会造成系统宕机。解决方案是将数据写入缓存,即使它在数据库中是空的。这是最简单粗暴的方法。无论从数据库中找到什么,都会写入缓存。缓存有效期可以设置的短一些,比如<=5min。使用BloomfilterBloomfilter的原理是,当你存储数据的时候,会通过hash函数映射到位数组中的K个点,同时将它们置1。当用户来查询A时,Bloomfilter中A的值为0,不打DB直接返回。使用Bloomfilter后,会出现误判的问题,因为它本身就是一个数组,多个值可能会落到同一个位置。理论上只要我们的数组长度足够长,误判的概率是一样的。会更低。做好参数校验,拦截非法参数,可以减少DB找不到数据的情况。我是后端程序员阿壮,搜索微信:科技猫,获取第一时间更新,下期见