Redis_缓存3_缓存异常(数据不一致、雪崩、击穿、穿透)
14.6缓存异常
四个方面
- 缓存中数据和数据库不一致
- 缓存雪崩
- 缓存击穿
- 缓存穿透
14.6.1数据不一致:
一致性包括两种情况
- 缓存中有数据,需要和数据库值相同
- 缓存中没有数据,数据库中的数据是最新值
如果不符合以上两种情况,则出现数据不一致的问题。
读写缓存
- 同步直写
- 异步写回
只读缓存
- 新增数据
- 数据直接写到数据库中,缓存不做操作。满足一致性两种情况的第2种。
- 删改数据
- 先删除缓存,后更新数据库。可能会导致,缓存删除成功,数据库更新失败。业务逻辑去访问数据时,缓存中查不到数据,缓存缺失,到数据库中查询,所以只拿到旧的数据。
- 如果新更新数据库,再删除缓存。可能会导致,数据库更新成功,缓存删除失败。数据库中的数据是新的值,缓存中存储的是旧值。再读取时,先从缓存中读取,读取到了旧值。
解决数据不一致的方案
- 重试机制:把删除的缓存值或要更新数据库值先存储到消息队列中(kafka消息队列)。
- 如果发现试了10次还不成功就会向服务器端报错
多线程访问的情况
- 先删除缓存,再更新数据库。
- 假设T1线程先删除缓存,再执行更新数据库。还未更新成功时,T2线程进行读取,发现缓存中没有数据,到数据库中读取,会读取到旧的数据。如果T2还将旧数据更新到缓存中,那T1线程再进行读取,也读到的旧值。
- 让T1线程先执行休眠一段时间。T1线程在休眠时间,让T2线程执行结束,会将数据重新写入缓存。T1线程再做一次缓存删除操作。“延迟双删”。
redis.delCache() db.update() Thread.sleep(2000) redis.delCache()
- 先更新数据库值,再去删除缓存
- 假设T1线程先删除或更新数据库中的值,还没来得及删除缓存时,T2线程就开始读取数据。T2会先从缓存中读取,缓存命中,T2拿到的就是旧的数据。直到T1将缓存中数据删除,其他线程再次读取,可以拿到新值.
| 并发操作 | 执行顺序 | 可能出现问题 | 问题描述 | 解决方案 |
|---|---|---|---|---|
| 没有 | 先删除缓存,后更新数据库 | 缓存删除成功,数据库更新失败 | 从数据库读到旧数据 | 重试(通过消息队列) |
| 有 | 先删除缓存,后更新数据库 | 缓存删除,未更新数据库,其他线程并发访问 | 并发线程从数据库读到旧值,并更新了缓存,其他线程都从缓存中读到旧值 | 延迟双删 |
| 没有 | 先更新数据库,后删除缓存 | 数据库更新成功,缓存删除失败 | 从缓存中读到旧值 | 重试(通过消息队列) |
| 有 | 先更新数据库,后删除缓存 | 数据库更新成功,未删除缓存,其他同线程并发访问 | 并发线程从缓存读到旧值 | 会有数据不一致情况短暂存在 |
14.6.2 缓存雪崩
大量的应用请求无法在redis中完成处理。缓存中读取不到数据,直接进入到数据库服务器。数据库压力激增,数据库崩溃,请求堆积在redis,导致redis服务器崩溃,导致redis集群崩溃,应用服务器崩溃,称为雪崩
原因1:缓存中有大量数据同时过期
解决方案:
- 页面静态化处理数据:对于不经常更换的数据,生成静态页
- 避免大量数据同时过期:为商品过期时间追加一个随机数,在一个较小的范围内(1~3分钟)。
- 构建多级缓存架构:redis缓存+nginx缓存+ehcache缓存
- 延长或取消热度超高的数据过期时间
- 服务降级
不同的数据采取不同的处理方式。
原因2:redis实例故障
解决方案:
- 服务熔断或限流处理
提前预防:
- 灾难预警:监控redis服务器性能指标,包括数据库服务器性能指标,CPU、内存、平均响应时间、线程数等
- 集群:有节点出一故障,主从切换。
14.6.2 缓存击穿
对某个访问频繁热点数据的请求。主要发生在热点数据失效
解决方案:
- 预先设定:电商双11,商铺设定几款是主打商品,延长过期时间
- 实时监控:监控访问量,避免访问量激增
- 定时任务:启动任务调度器,后台刷新数据有效期
- 分布式锁:可防止缓存击穿,但会有性能问题 (不推荐)
14.6.3 缓存穿透
要访问的数据在redis中不存在,在数据库中也不存在。
原因:
- 业务层误操作
- 恶意攻击
解决方案:
- 缓存空值或缺省值
- 使用布隆过滤器,快速判断数据是否存在
- 在请求入口前端进行请求检测
- 实时监控
- key加密
相关文章:
Redis_缓存3_缓存异常(数据不一致、雪崩、击穿、穿透)
14.6缓存异常 四个方面 缓存中数据和数据库不一致缓存雪崩缓存击穿缓存穿透 14.6.1数据不一致: 一致性包括两种情况 缓存中有数据,需要和数据库值相同缓存中没有数据,数据库中的数据是最新值 如果不符合以上两种情况,则出现…...
谁能讲清楚Spark之与MapReduce的对比
我们已经知道Spark是如何设计和实现数据处理流程的,这里我们 再深入思考一下,为什么Spark能够替代MapReduce成为主流的大数据处理框架呢?对比MapReduce,Spark究竟有哪些优势? 一 优势 1 通用性: 基于函数式编程思想,MapReduce将数据类型抽象为,k,v格式,并将数据处理…...
Android自定义侧滑Item
源码地址:https://github.com/LanSeLianMa/CustomizeView/tree/master/cehuaitem 使用方式一:XML布局中直接使用 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com…...
c++11 标准模板(STL)(std::basic_stringbuf)(三)
定义于头文件 <sstream> template< class CharT, class Traits std::char_traits<CharT>, class Allocator std::allocator<CharT> > class basic_stringbuf : public std::basic_streambuf<CharT, Traits> std::basic_stringbuf…...
Nodejs 第九章(模块化)
Nodejs 模块化规范遵循两套一 套CommonJS规范另一套esm规范 CommonJS 规范 引入模块(require)支持四种格式 支持引入内置模块例如 http os fs child_process 等nodejs内置模块支持引入第三方模块express md5 koa 等支持引入自己编写的模块 ./ …/ 等支…...
shell之正则表达式及三剑客grep命令
一、正则表达式概述 什么是正则表达式? 正则表达式是一种描述字符串匹配规则的重要工具 1、正则表达式定义: 正则表达式,又称正规表达式、常规表达式 使用字符串描述、匹配一系列符合某个规则的字符串 正则表达式 普通字符: 大小写字母…...
LeetCode 热题 100 JavaScript--33. 搜索旋转排序数组
整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nums[1], …,…...
并发编程 - 线程池中的常见面试题
目录 1. 线程池相比于线程有什么优点 2. 线程池的参数有哪些 3. 线程工厂有什么用 4. 说一下线程的优先级 5. 说一下线程池的执行流程 6. 线程池的拒绝策略有哪些 7. 如何实现自定义拒绝策略 8. 如何判断线程池中的任务是否执行完成 1. 线程池相比于线程有什么优点 有…...
将多个单独的 Excel 文件合并成一个,并添加标题行
要将多个单独的 Excel 文件合并成一个,并添加标题行,可以使用 Python 的 pandas 库。以下是一个示例代码,假设要合并的 Excel 文件都在同一个文件夹中: import os import pandas as pd # 指定文件夹路径 folder_path path/to/fo…...
VPN pptp和l2tp协议破解
代码下载地址: https://download.csdn.net/download/m0_37567738/88215516?spm1001.2014.3001.5501...
4.3、Flink任务怎样读取Kafka中的数据
目录 1、添加pom依赖 2、API使用说明 3、这是一个完整的入门案例 4、Kafka消息应该如何解析 4.1、只获取Kafka消息的value部分 4.2、获取完整Kafka消息(key、value、Metadata) 4.3、自定义Kafka消息解析器 5、起始消费位点应该如何设置 5.1、earliest() 5.2、lat…...
C语言实例_和校验算法
一、算法介绍 和校验(Checksum)是一种简单的纠错算法,用于检测或验证数据传输或存储过程中的错误。它通过对数据进行计算并生成校验和,然后将校验和附加到数据中,在接收端再次计算校验和并进行比较,以确定…...
安全加密框架图——Oracle安全开发者
Oracle安全开发者 ACLs 设计 ACLs(访问控制列表)时,可以根据以下思路进行设计: 所有者文件权限:确定文件的所有者能够对文件执行哪些操作,如读取、写入、执行等。这可以根据文件的性质和拥有者的职责来决…...
Android databinding 被多次定义
一、报错: AndroidStudio运行代码时,编译器报 Type androidx.databinding.Bindable is defined multiple times...... 二、解决: 点击 Build -> Clean Project,关闭编译器再打开即可。 三、解决过程: 在使用Andro…...
云原生周刊:Kubernetes v1.28 新特性一览 | 2023.8.14
推荐一个 GitHub 仓库:Fast-Kubernetes。 Fast-Kubernetes 是一个涵盖了 Kubernetes 的实验室(LABs)的仓库。它提供了关于 Kubernetes 的各种主题和组件的详细内容,包括 Kubectl、Pod、Deployment、Service、ConfigMap、Volume、…...
机器学习之分类模型
机器学习之分类模型 概述分类模型逻辑回归最近邻分类朴素贝叶斯支持向量机决策树随机森林多层感知机基于集成学习的分类模型VotingBaggingStackingBlendingBoosting 概述 机器学习分类模型通过训练集进行学习,建立一个从输入空间 X X X到输出空间 Y Y Y(…...
学习Vue:创建第一个Vue实例
当您开始探索 Vue.js,第一步就是创建一个 Vue 实例。Vue 实例是 Vue.js 应用程序的核心构建块,它使您能够将数据与用户界面连接起来,实现动态交互。在本文中,我们将详细介绍如何创建您的第一个 Vue 实例。 步骤1:引入 …...
JavaFx基础学习【二】:Stage
一、介绍 窗口Stage为图中标绿部分: 实际为如下部分: 不同的操作系统表现的样式不同,以下都是以Windows操作系统为例,为了使大家更清楚Stage是那部分,直接看以下图,可能更清楚: 有点潦草&…...
C语言——动态内存函数(malloc、calloc、realloc、free)
了解动态内存函数 前言:一、malloc函数二、calloc函数三、realloc函数四、free函数 前言: 在C语言中,动态内存函数是块重要的知识点。以往,我们开辟空间都是固定得,数组编译结束后就不能继续给它开辟空间了࿰…...
Redis数据结构——Redis简单动态字符串SDS
定义 众所周知,Redis是由C语言写的。 对于字符串类型的数据存储,Redis并没有直接使用C语言中的字符串。 而是自己构建了一个结构体,叫做“简单动态字符串”,简称SDS,比C语言中的字符串更加灵活。 SDS的结构体是这样的…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
