三个常见的缓存异常,分别是缓存雪崩、缓存击穿和缓存穿透。
缓存雪崩
缓存雪崩造成的结果是:数据库压力大
原因有两点:
原因一:缓存中有大量数据同时过期,且次数大量并发请求
方案:
发生雪崩前:避免给大量的数据设置相同的过期时间,过期时间增加一个较小的随机数(例如,随机增加 1~3 分钟)
发生雪崩时:(减少请求数目,数据库的压力就没有那么大了)
服务降级---------非核心业务数据(返回固定值:预定义信息、空值或是错误信息);
核心业务数据 (仍然允许查询缓存,如果缓存缺失,也可以继续通过数据库读取) 。
原因二:Redis 实例发生了宕机
方案:
Redis还未宕机:构建 Redis 缓存高可靠集群;
Redis已经宕机:采用服务熔断或请求限流机制;
前置准备:监测 Redis 缓存所在机器和数据库所在机器的负载指标,例如每秒请求数、CPU 利用率、内存利用率等。
如果我们发现 Redis 缓存实例宕机了,而数据库所在机器的负载压力突然增加,此时,就发生缓存雪崩了。
缓存击穿
热点数据在缓存中失效,访问该数据的大量请求,对后端数据库找出极大压力
方案:对于访问特别频繁的热点数据,不设置过期时间
缓存穿透
要访问的数据既不在 Redis 缓存中,也不在数据库中。缓存如同摆设,也出现了出现了不必要的IO和数据库请求。
原因有两点:
原因一:业务层误操作。(缓存中的数据和数据库中的数据被误删除了,所以缓存和数据库中都没有数据)
原因二:恶意攻击。
方案:
1,缓存空值或缺省值。
2,使用布隆过滤器快速判断数据是否存在
3,请求入口检测(常用,一个token码识别是否程序支持用户。恶意请求时直接把该用户拉入黑名单)
补充
布隆过滤器可以放在缓存和数据库的最前面:把Redis当作布隆过滤器时,当用户产生业务数据写入缓存和数据库后,同时也写入布隆过滤器,之后当用户访问自己的业务数据时,先检查布隆过滤器,如果过滤器不存在,就不需要查询缓存和数据库了,可以同时降低缓存和数据库的压力。
Redis布隆过滤器是使用String类型实现的,存储的方式是一个bigkey,建议使用时单独部署一个实例,专门存放布隆过滤器的数据,不要和业务数据混用,否则在集群环境下,数据迁移时会导致Redis阻塞问题。