转载,关于缓存穿透、缓存并发、缓存雪崩那些事

0 题记数据库

缓存穿透、缓存并发和缓存雪崩是常见的因为并发量大而致使的缓存问题,本文讲解其产生缘由和解决方案。后端

缓存穿透一般是由恶意×××或者无心形成的;缓存并发是由设计不足形成的;缓存雪崩是由缓存同时失效形成的,三种问题都比较典型,也是难以防范和解决的。本节给出通用的解决方案,以供在缓存设计的过程当中参考和使用。设计模式

1 缓存穿透缓存

缓存穿透指的是使用不存在的key进行大量的高并发查询,这致使缓存没法命中,每次请求都要穿透到后端数据库系统进行查询,使数据库压力过大,甚至使数据库服务被压死。服务器

咱们一般将空值缓存起来,再次接收到一样的查询请求时,若命中缓存而且值为空,就会直接返回,不会透传到数据库,避免缓存穿透。固然,有时恶意袭击者能够猜到咱们使用了这种方案,每次都会使用不一样的参数来查询,这就须要咱们对输入的参数进行过滤,例如,若是咱们使用ID进行查询,则能够对ID的格式进行分析,若是不符合产生ID的规则,就直接拒绝,或者在ID上放入时间信息,根据时间信息判断ID是否合法,或者是不是咱们曾经生成的ID,这样能够拦截必定的无效请求。架构

固然,每一个设计人员都应该对服务的可用性和健壮性负责,应该建设健壮的服务,让咱们的服务像不倒翁同样,所以,咱们须要对服务设计限流和熔断等功能,请参考《分布式服务架构:原理、设计与实战》中第1章关于微服务设计模式的内容。并发

2 缓存并发异步

缓存并发的问题一般发生在高并发的场景下,当一个缓存key过时时,由于访问这个缓存key的请求量较大,多个请求同时发现缓存过时,所以多个请求会同时访问数据库来查询最新数据,而且回写缓存,这样会形成应用和数据库的负载增长,性能下降,因为并发较高,甚至会致使数据库被压死。分布式

咱们一般有3种方式来解决这个问题。ide

分布式锁

使用分布式锁,保证对于每一个key同时只有一个线程去查询后端服务,其余线程没有得到分布式锁的权限,所以只须要等待便可。这种方式将高并发的压力转移到了分布式锁,所以对分布式锁的考验很大。

本地锁

与分布式锁相似,咱们经过本地锁的方式来限制只有一个线程去数据库中查询数据,而其余线程只需等待,等前面的线程查询到数据后再访问缓存。可是,这种方法只能限制一个服务节点只有一个线程去数据库中查询,若是一个服务有多个节点,则还会有多个数据库查询操做,也就是说在节点数量较多的状况下并无彻底解决缓存并发的问题。

软过时

软过时指对缓存中的数据设置失效时间,就是不使用缓存服务提供的过时时间,而是业务层在数据中存储过时时间信息,由业务程序判断是否过时并更新,在发现了数据即将过时时,将缓存的时效延长,程序能够派遣一个线程去数据库中获取最新的数据,其余线程这时看到延长了的过时时间,就会继续使用旧数据,等派遣的线程获取最新数据后再更新缓存。

也能够经过异步更新服务来更新设置软过时的缓存,这样应用层就不用关心缓存并发的问题了。

3 缓存雪崩

缓存雪崩指缓存服务器重启或者大量缓存集中在某一个时间段内失效,给后端数据库形成瞬时的负载升高的压力,甚至压垮数据库的状况。

一般的解决办法是对不一样的数据使用不一样的失效时间,甚至对相同的数据、不一样的请求使用不一样的失效时间,例如,咱们要缓存user数据,会对每一个用户的数据设置不一样的缓存过时时间,能够定义一个基础时间,假设10秒,而后加上一个两秒之内的随机数,过时时间为10~12秒,就会避免缓存雪崩

相关文章
相关标签/搜索