缓存击穿是数据访问redis缓存时,缓存过期,直接访问数据库
单一的高并发的数据失效
对于热点数据,我们不设置过期时间,这样就可以把请求都放在缓存中处理,充分把 Redis 高吞吐量性能利用起来。
或者过期时间再加一个随机值。设计缓存的过期时间时,使用公式:过期时间=baes 时间+随机时间。即相同业务数据写缓存时,在基础过期时间之上,再加一个随机的过期时间,让数据在未来一段时间内慢慢过期,避免瞬时全部过期,对 DB 造成过大压力
预先把热门数据提前存入 Redis 中,并设热门数据的过期时间超大值。
当发现缓存失效的时候,不是立即从数据库加载数据。
而是先获取分布式锁,获取锁成功才执行数据库查询和写数据到缓存的操作,获取锁失败,则说明当前有线程在执行数据库查询操作,当前线程睡眠一段时间在重试。
这样只让一个请求去数据库读取数据。
缓存穿透是:访问redis缓存以及数据库的时候都没有数据,导致每次访问数据都穿透缓存直接访问数据库,致使缓存成了摆设。
两个地方都不存在
当请求的数据不存在 Redis 也不存在数据库的时候,设置一个缺省值(比如:None)。当后续再次进行查询则直接返回空值或者缺省值。
在数据写入数据库的同时将这个 ID 同步到到布隆过滤器中,当请求的 id 不存在布隆过滤器中则说明该请求查询的数据一定没有在数据库中保存,就不要去数据库查询了。
大量的请求无法在 Redis 缓存系统中处理,请求全部打到数据库,导致数据库压力激增
大量热点数据同时过期,导致大量请求需要查询数据库并写到缓存;
Redis 故障宕机,缓存系统异常。
数据保存在缓存系统并设置了过期时间,但是由于在同时一刻,大量数据同时过期。系统就把请求全部打到数据库获取数据,并发量大的话就会导致数据库压力激增
要避免给大量的数据设置一样的过期时间,过期时间 = baes 时间+ 随机时间(较小的随机数,比如随机增加 1~5 分钟)。这样一来,就不会导致同一时刻热点数据全部失效,同时过期时间差别也不会太大,既保证了相近时间失效,又能满足业务需求。
当访问的不是核心数据的时候,在查询的方法上加上接口限流保护。比如设置 10000 req/s。如果访问的是核心数据接口,缓存不存在允许从数据库中查询并设置到缓存中。这样的话,只有部分请求会发送到数据库,减少了压力。
限流,就是指,我们在业务系统的请求入口前端控制每秒进入系统的请求数,避免过多的请求被发送到数据库。
一个 Redis 实例能支撑 10 万的 QPS,而一个数据库实例只有 1000 QPS。一旦 Redis 宕机,会导致大量请求打到数据库,从而发生缓存雪崩
在业务系统中,针对高并发的使用服务熔断来有损提供服务从而保证系统的可用性。服务熔断就是当从缓存获取数据发现异常,则直接返回错误数据给前端,防止所有流量打到数据库导致宕机。服务熔断和限流属于在发生了缓存雪崩,如何降低雪崩对数据库造成的影响的方案。
所以,缓存系统一定要构建一套 Redis 高可用集群,比如 《Redis 哨兵集群》或者 《Redis Cluster 集群》,如果 Redis 的主节点故障宕机了,从节点还可以切换成为主节点,继续提供缓存服务,避免了由于缓存实例宕机而导致的缓存雪崩问题。
缓存穿透指的是数据库本就没有这个数据,请求直奔数据库,缓存系统形同虚设。
缓存击穿(失效)指的是数据库有数据,缓存本应该也有数据,但是缓存过期了,Redis 这层流量防护屏障被击穿了,请求直奔数据库。
缓存雪崩指的是大量的热点数据无法在 Redis 缓存中处理(大面积热点数据缓存失效、Redis 宕机),流量全部打到数据库,导致数据库极大压力。