网站建设的相关知识/磁力天堂
学习材料:https://xiaolincoding.com/redis/cluster/cache_problem.html
缓存雪崩
什么是缓存雪崩
在面对业务量较大的查询场景时,会把数据库中的数据缓存至redis中,避免大量的读写请求同时访问mysql客户端导致系统崩溃。这种情况下,客户端进来的请求会先经过redis缓存查询,如果redis缓存过期则进而去查询mysql,而后再将返回的结果返回给客户端并再redis中进行缓存。于是就出现了一个问题,如果此时redis中大量的缓存数据过期或者redis宕机,那么客户端发起的请求还是会直接访问到数据库中,会使得数据库的压力剧增,导致数据库奔溃进而导致系统崩溃,这就是缓存雪崩问题。
示意图如下:
如何解决缓存雪崩问题
针对不同的诱因,有不同的应对策略;
1、大量数据同时过期
- 均匀设置过期时间;应该尽量避免将大量数据设置同一个过期时间,比如可以过期时间加上一个随机数,这样就可以保证数据不会在同一个时间过期。
- 互斥锁;当业务线程处理用户请求时发现请求的数据不在redis中,则加入一个互斥锁,保证这个时间内只有一个请求来进行缓存构建。拿不到锁的请求要么就返回空值或者默认值,要么就等构建完成之后再来获取缓存。(需要设置超时时间,避免拿到锁的请求崩溃后导致系统阻塞崩溃)
- 后台更新缓存;把更新缓存的工作交由后台线程定时更新。
2、Redis宕机
- 服务熔断;服务熔断就是一旦redis发生宕机,那么所有对缓存服务的访问全部返回错误,这样的话业务线会全部无法正常工作,但是系统不会崩溃。
- 请求限流机制;限流机制就是一旦redis发生宕机,只允许少量的请求访问数据库,再多的请求则在入口直接拒绝访问,这种可以减少对业务的影响。
- 构建redis缓存高可用集群;通过主从节点的方式构建redis缓存的高可用集群。
缓存击穿
什么是缓存击穿?
一般在秒杀活动这种大量访问某几个数据的情况下会出现此问题。也就是某几个热点数据同时过期,也会导致大量的请求击垮数据库,这种情况就叫做缓存击穿。
如何解决缓存击穿?
缓存击穿其实可以认为是缓存雪崩中缓存过期的一种情况,所以可以采用互斥锁或者后台更新缓存的方式来解决。
缓存穿透
什么是缓存穿透
在缓存和数据库中都没有相关的业务数据,此时就没办法构建缓存来服务后续的请求。当有大量这样的请求进入时,业务缓存中查询不到数据且无法构建缓存,就会不停的查询数据库导致数据库压力过大甚至系统崩溃,这就叫缓存穿透。
导致缓存穿透的原因有哪些
- 业务误操作将查询的数据进行了删除。
- 黑客攻击,故意大量访问某些读取不存在数据的业务
如何解决缓存穿透
- 限制非法请求;在API入口处进行判断请求是否合理,不合理的直接拦截避免进一步访问缓存或者数据库。
- 缓存空值或默认值;如果发现线上业务出现缓存穿透的现象,可以给这些值设置一个空值或者默认值返回,避免访问数据库。
- 使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在;
缓存雪崩、击穿、穿透的产生原因及其应对方案简述如下
补充问题
在面对并发请求时如何通过加互斥锁来避免缓存雪崩或者缓存击穿的问题?
在客户端请求进来之后,如果缓存中没有查询到数据,则使用setNX的方式来设置一个状态位,表示一种锁定状态。如果返回结果是0说明锁已经被占领,此时进行等待状态。如果返回结果是1则去请求数据库,将数据库中的数据读取到了之后再将此查询的key设置缓存共其他请求进行查询。这样就可以保证在并发请求中只会有一个请求查询数据库,其他请求只能等待重新发起查询,从而解决缓存并发问题。
解决缓存热点问题
那么缓存策略的总体思路:就是通过判断数据最新访问时间来做排名,并过滤掉不常访问的数据,只留下经常访问的数据,具体细节如下。
- 先通过缓存系统做一个排序队列(比如存放 1000 个商品),系统会根据商品的访问时间,更新队列信息,越是最近访问的商品排名越靠前。
- 同时系统会定期过滤掉队列中排名最后的 200 个商品,然后再从数据库中随机读取出 200 个商品加入队列中。
- 这样当请求每次到达的时候,会先从队列中获取商品 ID,如果命中,就根据 ID 再从另一个缓存数据结构中读取实际的商品信息,并返回。
- 在 Redis 中可以用 zadd 方法和 zrange 方法来完成排序队列和获取 200 个商品的操作。
如何保证缓存一致性
- 等待过期:等待redis中的key过期之后再重新去数据库读取数据进行更新。
- 优点
- 开发成本低、易实现
- 管理成本低,出现问题的概率小
- 缺点
- 完全依赖过期时间,时间太短容易导致缓存失效频繁,太长如果导致数据不一致。
- 优点
- 尝试删除:在更新数据库数据时尝试删除redis中的key,如果删除成功下次查询该缓存时就会查询到数据库层然后再去更新缓存
- 优点
- 延迟更小,数据一致性比方案一更高
- 实现成本低
- 缺点
- 如果数据库更新成功,但是redis删除失败,就会出现方案一的问题
- 在高并发场景容易出现连接数过多的问题
- 优点
- 主动更新:另外搭建一个消费服务订阅消息队列,再数据库数据更新时异步更新redis中的数据
- 优点
- 比较可靠,能保证更新操作至少在redis中执行了一次
- 解耦度高
- 缺点
- 实现成本高,需要另外增加消费服务
- 有时序性问题,如果因为网络延迟导致同一条数据的两次更新推送没有按照更新的顺序来,也会出现数据不一致问题
- 依然有客户端连接数过多问题
- 优点
- 订阅日志:搭建一个消费服务去订阅数据库的binlog日志,解析日志内的内容再去更新redis,实现与业务完全解耦
- 优点
- 在服务器压力不大的情况下,延迟最低
- 与业务解耦
- 解决了时序性问题,可靠性强
- 缺点
- 需要单独搭建一个同步服务,成本高
- 如果同步服务崩溃,会导致数据长时间不更新
- 优点
方案选型
如果数据变化多,且对数据的一致性要求高,那么直接不用缓存;
通常来说使用方案一就够了,如果要增加更新的即时性,就用方案二,如果对于延时要求高就用方案三或四,四能解决时序性问题。具体需要结合业务场景调整。
拓展:缓存如何保证高可用?
主从复制模式、哨兵模式、Redis Cluster模式
使用主从复制搭建的Redis集群可以实现读写分离的效果,一般使用一主多从,主写从读。但是这种模式有个问题就是一旦主从机有宕机的情况,就需要人工介入进行IP切换。
哨兵模式则是在主从复制的基础上进行了升级,加入了哨兵,也就是当主机宕机时会通过哨兵的检测判定是否下线,判定下线后会在其他的从机中选出一台主机然后调整其他从机的主机IP。
而Redis Cluster模式不仅有以上两种模式的优点,且其会将数据分节点存储,充分利用内存。Redis Cluster划分了16384个槽,每个key通过CRC16校验后对16384进行取模来决定放置哪个槽,集群的每个节点负责一部分的hash槽。这样就避免了不同节点中的内存数据冗余。
相关文章:

Redis篇之缓存雪崩、击穿、穿透详解
学习材料:https://xiaolincoding.com/redis/cluster/cache_problem.html 缓存雪崩 什么是缓存雪崩 在面对业务量较大的查询场景时,会把数据库中的数据缓存至redis中,避免大量的读写请求同时访问mysql客户端导致系统崩溃。这种情况下&#x…...

【深度学习笔记】3_2线性回归的从零实现
注:本文为《动手学深度学习》开源内容,仅为个人学习记录,无抄袭搬运意图 3.2 线性回归的从零开始实现 在了解了线性回归的背景知识之后,现在我们可以动手实现它了。尽管强大的深度学习框架可以减少大量重复性工作,但若…...

Apache Maven简介
Maven 简介 Apache Maven 是一个用于项目构建、依赖管理和项目信息管理的强大工具。它基于项目对象模型(Project Object Model,POM)进行构建,通过描述项目的结构和依赖关系来管理项目的构建过程。 以下是 Apache Maven 的一些关键原理和工作流程: 项目对象模型(POM)…...
#12解决request中getReader()和getInputStream()只能调用一次的问题
目录 1、背景 2、解决方案 2.1、自定义HttpServletRequestWrapper 2.2、JsonRequestHeaderParamsHelper 2.3、HttpServletRequestReplacedFilter 2.4、使用 1、背景 当前系统Content-Type为application/json,参数接收方式采用RequestBody和RequestParam&#…...

直接插入排序+希尔排序+冒泡排序+快速排序+选择排序+堆排序+归并排序+基于统计的排序
插入排序:直接插入排序、希尔排序 交换排序:冒泡排序、快速排序 选择排序:简单选择排序、堆排序 其他:归并排序、基于统计的排序 一、直接插入排序 #include<stdio.h> #include<stdlib.h> /* 直接插入排序&#…...

Java高级 / 架构师 场景方案 面试题(二)
1.双十一亿级用户日活统计如何用 Redis快速计算 在双十一这种亿级用户日活统计的场景中,使用Redis进行快速计算的关键在于利用Redis的数据结构和原子操作来高效地统计和计算数据。以下是一个基于Redis的日活统计方案: 选择合适的数据结构: …...

C/C++内存管理学习【new】
文章目录 一、C/C内存分布二、C语言中动态内存管理方式:malloc/calloc/realloc/free三、C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型四、operator new与operator delete函数五、new和delete的实现原理5.1 内置类型 六、定位new表达式(pl…...

选择适合你的编程语言
引言 在当今瞬息万变的技术领域中,选择一门合适的编程语言对于个人职业发展和技术成长至关重要。每种语言都拥有独特的设计哲学、应用场景和市场需求,因此,在决定投入时间和精力去学习哪种编程语言时,我们需要综合分析多个因素&a…...

【力扣每日一题】力扣106从中序和后序遍历序列构造二叉树
题目来源 力扣106从中序和后序遍历序列构造二叉树 题目概述 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 思路分析 后序遍历序列的最末尾数…...

logback日志回滚原理
日志输出主要依赖RollingFileAppender、TimeBasedRollingPolicy、SizeAndTimeBasedFNATP。 RollingFileAppender 主要用于生成日志文件,格式化内容再输出到日志文件TimeBasedRollingPolicy 设置回滚策略,如果发现日志输出的时间超过单位时间,…...

[C#]winform基于opencvsharp结合pairlie算法实现低光图像增强黑暗图片变亮变清晰
【低光图像增强介绍】 在图像处理领域,低光图像增强是一个具有挑战性的任务。由于光线不足,这些图像往往呈现出低对比度、高噪声和细节丢失等问题,严重影响了图像的视觉效果和后续分析的准确性。因此,开发有效的低光图像增强方法…...

React18源码: reconcliler启动过程
Reconcliler启动过程 Reconcliler启动过程实际就是React的启动过程位于react-dom包,衔接reconciler运作流程中的输入步骤.在调用入口函数之前,reactElement(<App/>) 和 DOM对象 div#root 之间没有关联,用图片表示如下: 在启…...

【RN】为项目使用React Navigation中的navigator
简言 移动应用基本不会只由一个页面组成。管理多个页面的呈现、跳转的组件就是我们通常所说的导航器(navigator)。 React Navigation 提供了简单易用的跨平台导航方案,在 iOS 和 Android 上都可以进行翻页式、tab 选项卡式和抽屉式的导航布局…...

CS50x 2024 - Lecture 8 - HTML, CSS, JavaScript
00:00:00 - Introduction 关于互联网是怎么工作的,如何在他的基础上构建软件 HTML和CSS是描述性语言 javascript一种编程语言,在浏览器上下文中很有用,使得界面更具交互性,也用于服务器 00:01:01 - Bingo Board 00:01:51 - T…...

C++:派生类的生成过程(构造、析构)
目录 派生类的生成过程 派生类的构造函数与析构函数: 构造函数: 派生类组合类的构造和析构: 构造函数和析构函数调用顺序: 派生类的生成过程 三步骤: 吸收基类(父类)成员:实现代…...

金蝶字段添加过滤条件
金蝶字段加过滤条件 F_PLDE_Date<GetValue(FDate) and F_PLDE_Date1>GetValue(FDate)...

SQLite 知识整理
写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。 目录 SQLite 类型数据…...

0基础JAVA期末复习最终版
啊啊啊啊啊啊啊啊啊啊,根据网上各位大佬的复习资料,看了很多大多讲的是基础但对内容的整体把握上缺乏系统了解。但是很不幸最终挂科了,那个出题套路属实把我整神了,所以我决定痛改前非,酣畅淋漓的写下这篇文章。。。。…...

【办公类-16-07-04】合并版“2023下学期 中班户外游戏(有场地和无场地版,一周一次)”(python 排班表系列)
背景需求: 把 无场地版(贴周计划用) 和 有场地版(贴教室墙壁上用) 组合在一起,一个代码生成两套。 【办公类-16-07-02】“2023下学期 周计划-户外游戏 每班1周五天相同场地,6周一次循环”&…...

chat GPT第一讲
计算机的语言奇迹:探秘ChatGPT的智能回答和写作能力 目前我们这个行业,最火的话题无疑是AI人工智能,类似ChatGPT这样的智能Ai,今天剩下的时间不多,每天一个主题,我给大家讲一下计算机回答问题和写作的能力,…...

JAVA工程师面试专题-Mysql篇
一、基础 1、mysql可以使用多少列创建索引? 16 2、mysql常用的存储引擎有哪些 存储引擎Storage engine:MySQL中的数据、索引以及其他对象是如何存储的,是一套文件系统的实现。常用的存储引擎有以下: Innodb引擎:In…...

vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
文章目录 1、原因2、思路3、解决方法3.1、使用alignTicks解决3.2、结合min和max属性去配置interval属性1、首先固定两边的分隔的段数。2、结合min和max属性去配置interval。 1、原因 刻度在显示时,分割段数不一样,导致左右的刻度线不一致,不…...

编程笔记 Golang基础 022 数组
编程笔记 Golang基础 022 数组 一、数组定义和初始化二、访问数组元素三、遍历数组四、数组作为参数六、特点七、注意事项 在Go语言中,数组是一种基本的数据结构,用于存储相同类型且长度固定的元素序列。 一、数组定义和初始化 // 声明并初始化一个整数…...

【kubernetes】二进制部署k8s集群之,多master节点负载均衡以及高可用(下)
↑↑↑↑接上一篇继续部署↑↑↑↑ 之前已经完成了单master节点的部署,现在需要完成多master节点以及实现k8s集群的高可用 一、完成master02节点的初始化操作 二、在master01节点基础上,完成master02节点部署 步骤一:准备好master节点所需…...

哈希表在Java中的使用和面试常见问题
当谈到哈希表在Java中的使用和面试常见问题时,以下是一些重要的点和常见问题: 哈希表在Java中的使用 HashMap 和 HashTable 的区别: HashMap 和 HashTable 都实现了 Map 接口,但它们有一些重要的区别: HashMap 是非线…...

LeetCode刷题小记 三、【哈希表】
1. 哈希表 文章目录 1. 哈希表写在前面1.1 理论基础1.2 有效的字母异位词1.3 两个数组的交集1.4 快乐数1.5 两数之和1.6 四数相加||1.7 赎金信1.8 三数之和(哈希法梦碎的地方)1.9 四数之和 Reference 写在前面 本系列笔记主要作为笔者刷题的题解&#x…...

Zookeeper选举Leader源码剖析
Zookeeper选举Leader源码剖析 leader选举流程 参数说明 myid: 节点的唯一标识,手动设置zxid: 当前节点中最大(新)的事务idepoch-logic-clock: 同一轮投票过程中的逻辑时钟值相同,每投完一次值会增加 leader选举流程 默认投票给自己,优先选择…...

Redis(十六)缓存预热+缓存雪崩+缓存击穿+缓存穿透
文章目录 面试题缓存预热缓存雪崩解决方案 缓存穿透解决方案 缓存击穿解决方案案例:高并发聚划算业务 总结表格 面试题 缓存预热、雪崩、穿透、击穿分别是什么?你遇到过那几个情况?缓存预热你是怎么做的?如何避免或者减少缓存雪崩?穿透和击穿有什么区别?他两是…...

[已解决]npm淘宝镜像最新官方指引(2023.08.31)
最新的配置淘宝镜像的淘宝官方提供的方法 npm config set registry https://registry.npmmirror.com原来的 registry.npm.taobao.org 已替换为 registry.npmmirror.com ,当点击 registry.npm.taobao.org 会默认跳转到 registry.npmmirror.com 如果你想将npm的下载…...

ffmpeg之avformat_alloc_output_context2
函数原型: int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat,const char *format_name, const char *filename); 功能: 根据format_name或者filename或者oformat查找输出类型,并且初始化ctx结构。 参数: ctx:AVFormatContext…...