(五)Redis 缓存异常、应对策略
1、缓存和数据库不一致
只要我们使用 Redis 缓存,就必然会面对缓存和数据库间的一致性保证问题,这里的“一致性”包含了两种情况:缓存中有数据且与数据库中的值相同、缓存中没有数据,最新值在数据库中。
对于读写缓存来说,要想保证缓存和数据库中的数据一致,就要采用同步直写策略,在业务应用中使用事务机制,来保证缓存和数据库的更新具有原子性。对数据一致性的要求不高的场景,可以使用异步写回策略。
只读缓存在新增数据时是符合数据一致性第二种情况的,但是在删改数据时,无论是操作缓存还是操作数据库,有一项失败,就会产生数据不一致的问题。具体情况如图:
针对这种情况可以引用重试机制来解决,具体来说,可以把要数据暂存到消息队列中。无论哪项操作失败,都可以从消息队列中重新读取这些值,然后再次进行删除或更新。如果删改成功,就把数据从消息队列中去除,以免重复操作,以此来保证数据一致性。多次重试仍然失败的话就需要业务层面预警来排查解决了。
除了操作失败的原因,实际当有大量并发请求时,应用还是有可能读到不一致的数据。根据删改缓存、数据库的先后顺序分为两种情况:先操作缓存和先操作数据库。通过引用“延迟双删”的操作,来保证先操作缓存后操作数据库的数据一致性问题,代码示意如下:
redis.delKey(X)
db.update(X)
Thread.sleep(N)
redis.delKey(X)
具体情况与应对措施总结如图:

2、雪崩
指大量的应用请求无法在 Redis 缓存中进行处理,到达数据库层面,导致数据库的压力激增。原因有二:
其一,缓存中有大量数据同时过期。
其二,Redis 缓存实例挂了。
原因一可以通过以下两个方法解决:
(1)微调过期时间:对于同一批数据设置不同的过期时间,如通过随机数延迟过期等。
(2)降级处理:非核心数据请求直接返回 空 或 错误 等预置信息,核心数据运行未命中缓存访问数据库。

原因二可以通过以下两个方法解决:
(1)熔断:拒绝缓存客户端的请求,保护数据库,防止整个系统崩溃,直到 Redis 缓存实例恢复正常,但是对业务应用的影响范围大。
(2)限流:允许部分请求到达 Redis 缓存,无法命中再访问数据库,减轻数据库压力,相对于熔断来说影响范围稍微缩小。
无论采取何种措施,雪崩都已经发生了,必定会影响到业务系统,所以要做好预防工作,构建 Redis 缓存高可靠集群,尽量避免事故。
3、击穿
指针对某个热点数据的请求,无法在缓存中处理,大量访问该数据的请求发送到了后端数据库,压力激增影响到其他请求,如下图:
为了避免缓存击穿给数据库带来的激增压力,对于访问特别频繁的热点数据,可以不设置过期时间了,全部在缓存中进行处理。

4、穿透
指要访问的数据既不在 Redis 缓存中,也不在数据库中,导致请求压力还是落到数据库,缓存也就成了“摆设”。如下图:
通常情况是由于业务数据被误删除,或者恶意攻击访问,有三种方案解决缓存穿透的影响:
(1)缓存空值或缺省值:针对穿透的数据,在 Redis 中缓存一个空值或是和业务层协商确定的缺省值,避免把大量请求发送给数据库。
(2)布隆过滤器
布隆过滤器由一个初值都为 0 的 bit 数组和 N 个哈希函数组成,数据入库则进行标记,过程如下:
- 使用 N 个哈希函数,分别计算这个数据的哈希值,得到 N 个哈希值。
- 我们把这 N 个哈希值对 bit 数组的长度取模,得到每个哈希值在数组中的对应位置。
- 我们把对应位置的 bit 位设置为 1,这就完成了在布隆过滤器中标记数据的操作。
当查询某个数据时,按照哈希函数的计算结果,查看 bit 数组中这 N 个位置上的 bit 值,只要有一个不为 1,这就表明布隆过滤器没有对该数据做过标记。当缓存穿透发生,布隆过滤器的快速检测特性可以帮数据库阻挡大部分的压力。例子如下图:
(3)前端请求过滤:在请求入口前端进行合法性检测,把恶意的请求(如请求参数不合理、非法值或请求字段不存在)直接过滤掉。
小结
雪崩、击穿、穿透,这三类异常问题从成因来看,前两个主要是因为数据不在缓存中了,而穿透则是因为数据既不在缓存中,也不在数据库中。当雪崩或击穿发生时,一旦数据库中的数据被再次写入到缓存后,应用又可以在缓存中快速访问数据了,数据库的压力也会相应地降低,而穿透发生时,Redis 缓存和数据库会同时持续承受请求压力。
对应的熔断、降级、限流这些方法都是属于“有损”方案,在保证数据库和整体系统稳定的同时,会对业务应用带来负面影响。降级时,有部分数据的请求就只能得到错误返回信息,无法正常处理。熔断时,整个缓存系统暂停,影响的业务范围更大。流机时,整个业务系统的吞吐率会降低,并发处理能力减弱,影响到用户体验。
所以,应当尽量使用预防式方案,总结如下:
- 雪崩,合理地设置数据过期时间,以及搭建高可靠缓存集群。
- 击穿,在缓存访问非常频繁的热点数据时,不要设置过期时间。
- 穿透,提前在入口前端实现恶意请求检测,或者规范数据库的数据删除操作,避免误删除。

(五)Redis 缓存异常、应对策略的更多相关文章
- Redis缓存异常的容错实现方法( .net)
using DotNet.Log; /// <summary> /// Redis缓存辅助类 /// /// 修改纪录 /// /// 2015-10-26 版本:1.0 SongBiao ...
- redis 缓存用户账单策略
最近项目要求分页展示用户账单列表,为提高响应使用redis做缓存,用到的缓存策略和大家分享一下. 需求描述:展示用户账单基本信息以时间倒序排序,筛选条件账单类型(所有,订单收入.提现.充值...). ...
- 第三方网站返回hybrid app H5页面缓存问题应对策略
最近负责公司各产品线购买模块的开发,各项功能如期开发完成后测试那边反馈回来一个问题:IOS手机在点击支付宝购买后,跳转到支付宝网站时不输入支付密码,直接点返回,返回到我们自己的APP购买界面发现页面显 ...
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- Redis缓存篇(四)缓存异常
这一节,我们来学习一下缓存异常.缓存异常有四种类型,分别是缓存和数据库的数据不一致.缓存雪崩.缓存击穿和缓存穿透. 下面通过了解这四种缓存异常的原理和应对方法. 缓存和数据库的数据不一致 缓存和数据库 ...
- 转:Redis 缓存策略
转:http://api.crap.cn/index.do#/web/article/detail/web/ARTICLE/7754a002-6400-442d-8dc8-e76e72d948ac 目 ...
- Redis总结(五)缓存雪崩和缓存穿透等问题
前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhong/category/771056.html .今 ...
- redis 缓存策略
redis 缓存策略配置项:maxmemory <bytes>maxmemory-policy noeviction 触发时机:每次执行命令(processCommand)的时候会检测 w ...
- Redis总结(五)缓存雪崩和缓存穿透等问题(转载)
前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhong/category/771056.html .今 ...
- Redis缓存策略设计及常见问题
Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的选 ...
随机推荐
- 动态修改manifest.json
点击查看代码 // h5开发环境 const h5Dev = { baseUrl: 'https://devh5.....' } // h5测试环境 const h5Test= { baseUrl: ...
- 圣诞快乐 - Splashtop 2020 年回顾及未来展望
我们很高兴 Splashtop 的远程访问解决方案能够在这个充满挑战的时期为全球的组织和教育机构提供帮助. 实际上,2020 年 Splashtop 的每日使用量增加了400%!不仅如此,我们还增 ...
- 【源码】蚁群算法TSP问题可视化
ACO.Visualization项目 本项目演示蚁群算法求解旅行商问题的可视化过程,包括路径上的信息素浓度.蚁群的运动过程等.项目相关的代码:https://github.com/anycad/AC ...
- sentinel-dashboard.jar 安装
本文涉及的基本概念: 几种服务限流方式:熔断:拒绝流量访问,当系统恢复正常时在关闭熔断服务降级:将次要服务降级,停止服务,将系统资源释放出来给核心功能延迟处理:在前端设置一个流程缓冲池,将所有的流程全 ...
- EL表达式与JSTL简单入门
更多博文请关注:听到微笑的博客 EL概述 EL(Express Lanuage)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写,EL出现的目的是要替代jsp页面中脚本的编写. 简单来说EL表达式 ...
- OpenCV笔记(10) 相机模型与标定
万圣节快乐! 1. 相机模型 针孔相机模型:过空间某特定点的光线才能通过针孔(针孔光圈),这些光束被投影 到图像平面形成图像. 将图像平面在针孔前方,重新把针孔相机模型整理成另一种等价形式, 实际上, ...
- 鸿蒙HarmonyOS实战-ArkTS语言基础类库(并发)
一.并发 并发是指在一个时间段内,多个事件.任务或操作同时进行或者交替进行的方式.在计算机科学中,特指多个任务或程序同时执行的能力.并发可以提升系统的吞吐量.响应速度和资源利用率,并能更好地处理多用户 ...
- css作用 文本属性 颜色属性
Css作用:美化页面 各种css属性 接触的 css属性 width: height: background: Color 选择符和声明 声明包括 属性:属性值 选择符:{ 属性:属性值 } 1:文本 ...
- redux中集成immutable.js
安装redux-immutable redux中利用combineReducers来合并reducer并初始化state,redux自带的combineReducers只支持state是原生js形式的 ...
- React事件处理 事件绑定 事件对象
React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同: React 事件的命名采用小驼峰式,而不是纯小写. onClick onChange 使用 JSX 语法时你需要传入一个 ...