Redis 雪崩:
在某个时间段,Redis的部分节点或者全部节点都挂掉了,导致Redis无法提供服务,请求全部转移到后端数据库,从而压垮数据库的情况。Redis雪崩通常由于某些原因导致缓存中的数据批量失效或者过期,导致后续请求都落到了数据库上,使得数据负载和请求量急剧增大,最终导致数据库的性能急剧下降甚至挂掉。
造成Redis雪崩的原因可能有:
- Redis本身故障
- Redis部署问题,如不合理的分布式部署、过于集中的部署等;
- 数据库请求的热点集中,如在某个时间段上某个关键字的请求量激增;
- 大批量缓存数据失效或者过期;
- 攻"坤"和误用,如故意大批量的请求、故意设置全部过期时间等。
为防止Redis雪崩,可以从以下方面入手:
- 合理设置缓存策略,如对热点数据设置较短的过期时间,以避免大批量缓存数据同时失效的情况;
- Redis集群化部署,尽量避免全部节点挂掉的情况;
- 备份数据源,如设置数据备份或者多副本存储;
- 对关键词请求做限流,避免低效、高频请求对数据库造成的影响;
- 监控数据库的访问情况,一旦出现异常一定要及时发现并排查问题
Redis 缓存击穿:
指在高并发场景下,一个或多个热点的缓存数据过期或被删除,导致大量并发请求落到了后端数据库上,造成数据库压力剧增,甚至导致服务宕机的情况。
出现Redis缓存击穿的原因可能有以下几点:
- 缓存数据失效:由于缓存数据的有效期到了或被手动删除,导致大量请求需要重新查询数据库获取数据。这种情况在高并发场景下容易出现。
- 热点数据集中:由于业务需求或者其他原因,部分数据被频繁访问,成为热点数据。当这些数据集中到一个缓存 key 上时,容易发生缓存击穿。
- 预热不足:当应用首次启动或者数据发生变化后,需要将数据加载到缓存中。但是如果数据量很大或者预热不及时,可能会导致缓存击穿。
- 服务器宕机:当 Redis 服务器宕机或者 Redis 所在服务器出现问题时,会导致缓存不能正常使用,进而导致缓存击穿。
为避免Redis缓存击穿,可以从以下方面入手:
- 设置永不过期的热点数据,或者采用互不干扰的数据切分策略,以避免大量的请求打入单个热点造成的击穿问题;
- 针对可能出现的缓存击穿,采用分布式锁或互斥锁的方式,保证只有一个请求能够进行数据库查询,并且将查询结果写入缓存,其他请求则直接从缓存读取。
- 如果读压力远大于写压力,可以使用互斥锁空置缓存,避免历史垃圾数据长期占用缓存空间。
- 对客户端请求进行限流,避免大量请求在短时间内同时到达,造成缓存打满和数据库瞬时压力过大的情况。
Redis缓存穿透:
缓存穿透是指恶意攻"坤"者通过构造不存在于缓存和存储介质中的键值对,来请求Redis的过程,从而导致缓存被击穿,应用负载升高以及后端存储压力增加,最终影响服务的可用性和稳定性。
Redis缓存穿透的原因可能有以下几点:
- 缓存和存储介质不同步造成的穿透:在缓存层时,由于某些异步操作或者数据处理逻辑错误,导致某些数据未及时从后端存储同步到缓存中。当恶意攻"坤"者将这些未同步的数据作为查询条件的一部分,访问应用程序时,缓存不会命中,从而导致缓存穿透。
- 恶意构造查询条件导致的穿透:恶意攻"坤"者可能会故意构造一些不存在于缓存和存储介质中的数据作为查询条件的一部分,来访问应用程序,导致缓存与后端存储都无法命中,从而引发穿透。
- 应用程序缓存处理逻辑不完善造成的穿透:应用程序可能会存在缓存处理逻辑不完善的情况,例如没有对查询条件进行严格的校验或者未考虑到缓存失效的情况,从而导致缓存穿透。
为了防止Redis缓存穿透攻"坤",可以采用一些防御措施,例如:
- 对前端传入的查询参数进行限制和过滤。
- 对缓存不存在的数据做标记或者直接将请求拦截。
- 引入布隆过滤器,将查询条件加入到布隆过滤器中,如果查询条件不在布隆过滤器中直接拦截请求。