redis——缓存雪崩,缓存击穿,缓存穿透

缓存雪崩

缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决:

  1. 设置随机过期时间:对于热点数据,可以不设置过期时间,或者为缓存数据设置随机的过期时间,以避免大量数据同时过期,减少对数据库的压力。例如,可以将基础过期时间加上一个随机值来设计缓存的过期时间,这样数据会在未来逐渐过期,避免同时过期造成数据库压力过大。

  2. 预热缓存:提前将热点数据加载到Redis中,并设置一个较长的过期时间,这样可以减少缓存失效的发生。

  3. 使用分布式锁:当检测到缓存失效时,不是立即从数据库加载数据,而是先尝试获取分布式锁。成功获取锁后,再执行数据库查询和缓存数据写入操作。如果获取锁失败,则表示当前有其他线程正在执行数据库查询操作,当前线程可以稍作休眠后重试。这样可以确保只有一个请求去数据库读取数据。

  4. 缓存空值:当请求的数据在Redis和数据库中都不存在时,可以设置一个默认值(例如:None)。这样,当后续再次查询时,直接返回空值或默认值,避免再次访问数据库。

  5. 使用布隆过滤器:在数据写入数据库时,将ID同步到布隆过滤器中。当请求的ID在布隆过滤器中不存在时,意味着请求查询的数据一定不在数据库中,因此不需要去数据库查询。布隆过滤器需要缓存全部的键,因此适合数据量不大的情况,例如少于10亿条数据,因为10亿条数据大约会占用1.2GB的内存。

  6. 接口限流:对于非核心数据的访问,可以在查询方法上添加接口限流保护,例如设置每秒10000个请求。如果核心数据接口被访问,缓存不存在,则允许从数据库查询并设置到缓存。这样,只有部分请求会被发送到数据库,减轻压力。

  7. 构建高可用缓存集群系统:为了防止缓存系统故障导致的缓存雪崩,必须构建Redis高可用集群,如"Redis Sentinel Cluster"或"Redis Cluster Cluster",如果Redis的主节点失败,从节点也可以切换成为主节点,继续提供缓存服务,避免因缓存实例宕机导致的缓存雪崩。

缓存击穿

是指一个系统中的缓存数据在被请求时恰好失效,而此时如果有大量并发请求同时到达,这些请求都会穿透缓存,直接打到后端数据库上。这种情况可能会导致数据库瞬时压力过大,甚至可能因为无法承受突如其来的高并发流量而崩溃。 (与缓存雪崩不同的是击穿指一个数据而雪崩是多个数据)

解决

  1. 加锁策略:在缓存失效时,使用分布式锁来确保只有一个请求能够访问数据库并重新加载缓存,其他请求则等待或重试。

  2. 缓存空对象:如果数据库查询结果为空,仍然将这个空结果缓存起来,这样即使缓存失效,请求也会从缓存中快速失败,而不是每次都去数据库查询。

  3. 设置合理的过期时间:根据数据的访问频率和更新频率来设置缓存的过期时间,避免缓存在同一时间大量过期。

  4. 使用随机过期时间:为缓存设置一个随机的过期时间,这样即使多个请求同时到达,也不大可能同时击穿缓存。

  5. 读写分离:通过数据库的读写分离,将缓存击穿的流量分散到多个数据库副本上,减轻单个数据库的压力。

  6. 限流和降级:在系统检测到缓存击穿时,启动限流措施,减少对数据库的访问压力,同时可以启动降级策略,提供备选的服务方案。

缓存穿透

是指请求查询数据库中不存在的数据,由于在缓存中也没有这些数据的记录,因此请求会直接穿透缓存,每次都直接访问数据库。

解决

  1. 缓存空值:当数据库查询结果为空时,仍然将这个空结果缓存起来,并设置一个较短的过期时间。这样,下次同样的请求会直接命中缓存,而不会去查询数据库。

  2. 布隆过滤器(Bloom Filter):在缓存之前使用布隆过滤器来检查一个请求是否可能命中。布隆过滤器可以快速判断一个元素是否在一个集合中,从而避免对数据库的无效查询。

  3. 预加载缓存:对于可能被频繁查询的数据,可以提前将它们加载到缓存中,即使这些数据在数据库中暂时不存在,也可以在缓存中设置一个默认的空值响应。

  4. 限制频繁请求:通过限流措施来限制对同一数据的频繁访问,减少对数据库的压力。

  5. 使用互斥锁:当检测到缓存未命中时,使用互斥锁来确保只有一个线程去查询数据库,并将结果缓存起来,其他线程则等待或重试。

  6. 数据库查询结果缓存:即使查询结果为空,也将其缓存起来,并设置一个合理的过期时间,这样在过期时间内相同的查询将直接返回缓存结果。

相关推荐
hans汉斯几秒前
【软件工程与应用】基于大数据的应急救援云平台构建应用研究
大数据·数据库·人工智能·物联网·系统架构·云计算·汉斯出版社
键来大师几秒前
Android16 RK3576 系统清理缓存
android·缓存·framework·rk3588·android15
流绪染梦3 分钟前
多表联查时处理一对多的信息,将子表字段放入数组
java·数据库
Ghost Face...4 分钟前
深入解析dd命令:缓存与磁盘速度之谜
linux·缓存
悦数图数据库8 分钟前
国产图数据库:开启数据新“视”界 悦数科技
数据库·人工智能
啊巴矲11 分钟前
小白从零开始勇闯人工智能Linux初级篇(Navicat Premium及MySQL库(安装与环境配置))
数据库·人工智能·mysql
我要精通C++13 分钟前
从源码看nginx的缓存功能
运维·nginx·缓存
en-route13 分钟前
Redis 作为消息队列的三种使用方式与 Spring Boot 实践
数据库·spring boot·redis
GreatSQL社区17 分钟前
GreatSQL MGR三节点基于时间点恢复
数据库·oracle
李慕婉学姐19 分钟前
Springboot遇见宠物生活馆系统设计与实现n6ea5118(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·宠物