从八股文到奇怪的缓存一致性问题

news2024/11/12 14:13:12

        本文是最近看阿里云开发者的一遍奇怪的缓存一致性问题的总结与心得,原文放在文章末尾

缓存穿透、缓存击穿、缓存雪崩

缓存穿透、缓存击穿和缓存雪崩都是系统中可能遇到的问题,特别在高并发场景下。

缓存穿透

        与后两者不同,缓存穿透是查询不存在的数据。当去查询不存在的数据,由于缓存不命中(数据根本不存在),请求就会穿过缓存,去查询数据库。如果有大量的此类请求,就会导致数据库的压力骤增,严重会让数据库直接垮掉。

         在大多数情况下缓存穿透是由恶意请求导致的,所以防止缓存穿透某种意义上就是拦截恶意请求

解决方案:       

1.通过布隆拦截器

        在缓存之前使用布隆拦截器,一种空间效率高的数据结构,用来检测一个元素是否在集合中。tips:布隆过滤器会存在误判的可能:判断存在则可能不存在,判断不存在一定不存在。但是依旧可以通过他过滤掉绝大部分无效请求。

注:在分布式场景中,布隆过滤器也需要分布式的,可以使用Redisson提供的来实现

        由于过滤器说不存在就不存在,因此在新增数据时都要先写布隆过滤器,再写库。

        如果在升级系统的过程中引入,则需要现将db中的历史数据先导入到布隆过滤器中。

        布隆过滤器并不支持删除数据,因此在长时间之后,数据库的数据可能发生大变动,而布隆过滤器中的数据会一直累计,存在大量无用数据,导致误判的概率增加,防护能力也会降低。那么我们就必须要定期重置布隆过滤器。在一个月黑风高的夜晚降级掉布隆过滤器的防护,清空内容,在新数据写入的同时,再将历史数据导入。

2.增加空值

        将数据库中的非法值当做合法值存储在内存当中。这样会导致缓存中有垃圾数据,就需要设定一定的过期时间。在插入数据的时候也需要清空缓存数据。在我的售票系统中用户查询车次中就用到了此点,将查询不到的依旧放入到缓存当中,同时设置一定的过期时间。
        增加空值也有弊端,当面对恶意请求随机生产key访问的时候,不但会打垮数据库,还会将缓存写满,可能导致逃掉掉有效的热点的key。因此也需要一定的保护措施

保护措施:

  • 处理恶意请求引起的缓存穿透,可以采用限流的方式。在使用token下将token作为唯一标识,以及其他的比如ip(可能导致连坐,范围误杀),记录该唯一标识在指定时间内的无效请求数量,并在每次记录完后与配置的阈值进行比较,在时间窗口内的数量超过则返回限流结果。(动态 窗口禁流/静态窗口禁流)。
  • 在某些场景下可以通过给业务增加特殊效验位来过滤恶意请求。比如:查询订单中,查询入参是订单id,攻击方发起攻击需要构造不存在的订单id。如果我们的订单是简单的数字,那么就可能轻易被构建出。但是如果我们存在一些隐形规律,那么就没有那么容易构建。
    用某一个id算法生成订单id:123456 ,基于此id取最大值和最小值追加在id后面,形成最终id:12345661.就可以通过简单的算法分析合理性。

缓存击穿:

        某个热点缓存数据访问的频率很高,但是热点存在过期时间,过期之后导致大量的热点请求直接访问数据库,数据库压力瞬间骤增。

解决方案:

  1. 设置热点数据永不过期:设置一个较长时间的过期时间,相对永不过期
    1. 首先识别热key,可以通过基于基础中间件提供的能力统计
    2. 要锁定热key。大多数的数据一致性方案就会在更新数据库数据时删除缓存,如果不进行锁定,删除了依旧会遭遇缓存击穿。锁定热key又分为两种:热key对应的数据不允许修改/热key对应的缓存在数据库数据修改时不进行更新
  2. 通过队列让击穿流量排队
    将击穿后的流量放入队列中,并发控制流量,成为消费者
    :可以通过消息队列中间件,将逻辑部分分为两部分,分为处理请求的机器和接受请求的机器,同时把处理结果同步回去。

(让我想到在我的售票系统中,在用户购票环节中将令牌大闸拿取令牌,同时生成一个订单表,与处理订单相分离,通过mq发送信息给另一端。同时由一开始的对每个订单的处理,转化为对每个车次所有订单的处理,处理完之后修改订单表的信息。前台通过另一个接口间隔时间轮训查看订单信息,成功则返回)。

        在一般的业务中可能只需要内存队列就可以满足需求。

        使用内存队列,每个队列只有一个消费者。数据库的压力在最坏下为服务集群n的数量。通过队列整流后,将大并发变为小并发,那么请求的等待时间就可能会被延长。可以 通过增加消费者来缓解此问题。      

3. 分布式信号量+睡眠(类似分布式锁,不过并分拿不到锁就返回)。

        击穿流量在访问数据库前需要设置一个分布式信号量,设置成功则访问库并把结果放在缓存中。设置不成功则睡眠一段时间,然后到缓存获取数据,不访问数据库。

缓存雪崩

        缓存雪崩类似缓存击穿,不过缓存雪崩是指大量缓存信息在同一时间消失,导致所有的请求大量访问数据库。

解决方案:

  1. 增加随机值,在原本的过期时间上添加一个Random,让过期时间不统一
  2. 通过队列让流量排队

数据一致性问题

        当我们的数据在 多个地方存储的时候(比如缓存和数据库),这些地方的数据可能会出现不一致的情况。可能是由于缓存更新滞后、系统故障或其他原因引起。数据一致性是分布式系统设计中的一项挑战,尤其在读写非常频繁的系统中。

数据一致性问题:当数据被更新时,如果缓存中的相应数据没有立即更新,那么缓存系统将向应用程序提供旧数据。导致应用程序得到不一样的结果,影响用户体验。

在分布式系统中,可以根据系统的设计与需求选择实时强一致性最终一致性

实时强一致性:

        定义:实时强一致性保证了在任何时刻,任何客户端看到的数据都是一样的。在分布式系统中实现强一致性就意味着,一个操作完成以后,所有的客户端立即都能看到这个操作的结果

适用场景:事务性强,对数据一致性有高要求的系统。比如:银行或财务系统

最终一致性:

        定义:最终一致性是指系统会保证在没有新的更新操作下,经过一段时间以后,数据才会被同步到存储的地方中。在这种情况下,数据的副本可能会存在数据不一致的问题。

        适用场景:对实时性要求不高,能够容忍短时间数据不一致场景,比如聊天信息的传递,数据分析

原文中奇怪的数据一致性问题

push中心将后台配置端(只有查询流量没有增删改,dps较高)和前台投放端(增删改)分别部署在两个应用中,都需要配置数据库连接,配置缓存

前台投放端:与用户打交道,将业务广告等推送给用户

后台配置端:面向商家、数据分析师等确保广告能够按照预期的目标和策略执行。

主要包含了四条链路

链路一:投稿端:先去查询本地缓存,未命中则查询tair,查到后更新本地缓存。以tair作为数据库的方式

链路二:采用一个定时任务,按时刷新db中的数据到tair中。

        定时任务可能得实现方式:

        1.暴力全量刷新,redis中缓存的数据过期时间要大于定时任务运行时间。但是在数据量大的情况下不适用。

        2.数据库中的数据更新有时间戳,定时任务每次拉取上次任务开始时间搓减去定时任务执行时间所得到的时间戳之后的数据,将数据刷新到redsi中。redis中的数据设置为永不过期(删除作为软删除)

        这种定时任务,相邻两个任务有一定的数据重叠,防止漏掉数据。如果本地任务负责的数据较多可能在短时间内无法完成,那么下个任务由于抢不到锁就会在后续某个间隔开始执行,因此需要使用上一个定时任务开始的时间。

链路三:为后台配置端的查询操作,先查tair,没有则查数据库,并更新到数据库中

链路四:为写入操作,先删除tair中的缓存信息后更新数据库。

核心问题:链路一与链路四可能存在冲突,当我们删除tair中的缓存信息后,定时任务还没刷新前,那么此时链路一来查询就会导致缓存穿透的问题(本地缓存中没有,tair中也没有)。

原文给出的解决方案:

方案一:修改配置端,问题的原因为删除缓存后出现问题。那么索性不删除,采取双写。

将缓存的修改放在了数据库事务中进行,最大的问题在于如果写缓存虽超时,但是数据实际已经写入tair中,这时抛出的异常会导致数据库事务回滚,而数据库没有,tair中有,会形成僵尸数据。(可以通过scan的方式定期清理)。

方案二:修改投放端:(存在问题)

tair未命中,去查数据库并刷新tair

        存在一个数据不一致性的问题,当配置单删缓存后,更新数据库前。此时投放端去tair中查找但是未命中,接着去DB中查后更新到tair中(查一般比增删改要快)。配置端未刷新缓存就会导致缓存失效前一致取到的是旧值。

原文应该采用了方案一的设计。并没有通用的方案,只有适合当前系统特性和业务需求的方案。

另外我再说另一种常见的就是双删,在配置端删除缓存后修改DB后延迟再次删除缓存中的数据。但是延迟的时间不易确定,太短无效,太长可能导致长时间不一致。。

原文地址:奇怪的缓存一致性问题 (qq.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2105103.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

10.10 层次化网络模型和综合布线系统

层次化网络模型 综合布线系统 真题

前端登录鉴权——以若依Ruoyi前后端分离项目为例解读

权限模型 Ruoyi框架学习——权限管理_若依框架权限-CSDN博客 用户-角色-菜单(User-Role-Menu)模型是一种常用于权限管理的设计模式,用于实现系统中的用户权限控制。该模型主要包含以下几个要素: 用户(User)…

基于微信的热门景点推荐小程序的设计与实现(论文+源码)_kaic

摘 要 近些年来互联网迅速发展人们生活水平也稳步提升,人们也越来越热衷于旅游来提高生活品质。互联网的应用与发展也使得人们获取旅游信息的方法也更加丰富,以前的景点推荐系统现在已经不足以满足用户的要求了,也不能满足不同用户自身的个…

Leetcode—72. 编辑距离【中等】

2024每日刷题&#xff08;158&#xff09; Leetcode—72. 编辑距离 动态规划算法思想 实现代码 class Solution { public:int minDistance(string word1, string word2) {const int m word1.length();const int n word2.length();vector<vector<int>> dp(n 1,…

Multi-Mode DOA Estimation AND Relax Super Resolution DOA

之前看到加特兰的新品发布会上&#xff0c;PPT写的一些算法信号处理流程图&#xff0c;这里记录学习一下自己的思考&#xff1a; 原始数据采样数据预处理距离维FFT通道间DDMA数据分离非相干累计RV-MAP coarse-cfar fine CFAR(multi-Mode DOA Estimation): 舱内的CPD信号处理流…

分支线定向耦合器宽带化设计和ADS仿真

分支线定向耦合器宽带化设计和ADS仿真 工程下载链接&#xff1a;分支线定向耦合器宽带化设计和ADS仿真-ADS工程文件 之前经常分析分支线定向耦合器&#xff0c;例如在15、ADS使用记录之耦合器设计和基于AWR的微带线分支线耦合器设计-从原理到版图中都有涉及&#xff0c;但是由…

Axure中继器动态数据图表制作

在Axure RP中&#xff0c;中继器&#xff08;Repeater&#xff09;是一个非常强大的工具&#xff0c;它允许设计者动态地展示和交互数据&#xff0c;进而创建各种复杂的数据可视化图表&#xff0c;如柱状图、条形图、堆叠图、散点图和对比图。以下将详细介绍如何使用中继器来设…

solidworks模型导出urdf(超详细)

目录 写在前面的话1 solidworks 文件2 安装sw2urdf插件3 完整步骤3.1 设置基准轴3.2 设置点3.3 设置坐标轴3.4 设置sw2urdf参数3.5 导出可能的问题3.6 ros2 编译3.7 成功结果画面 写在前面的话 刚进组1个月&#xff0c;我的博士研究方向是自动驾驶&#xff0c;还没入门&#x…

火山引擎携手Keep,让线上健身更快更稳

今年年初&#xff0c;一部《热辣滚烫》又掀起了健身塑型风潮。作为健身领域的佼佼者&#xff0c;Keep 为用户提供全面的健身方案&#xff0c;以帮助用户实现健身目标。随着短视频运动的流行&#xff0c;Keep 覆盖的运动品类超过60类&#xff0c;同时不断尝试直播等新的内容承载…

Oceanbase 透明加密TDE

官方文档&#xff1a;数据库透明加密概述-V4.3.2-OceanBase 数据库文档-分布式数据库使用文档 OceanBase 数据库社区版暂不支持数据透明加密。 数据存储加密是指对数据和 Clog 等保存在磁盘中的数据进行无感知的加密&#xff0c;即透明加密&#xff08;简称 TDE&#xff09;。…

【时时三省】(C语言基础)指针进阶 例题

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 字符数组例题&#xff1a; arr后面放了六个字符 所以这个数组的元素个数就是6 第一个arr 因为他计算的是一整个数组的大小 就是打印6 第二个arr0 arr没有单独放在它的内部 所以它计算的就是…

flunet瞬态处理时均问题

fluent处理时均问题 最近遇到个同学&#xff0c;处理心脏跳动的时均问题&#xff0c;由于仅想取部分稳定时间段的时均数据&#xff0c;fluent的自动采样仅能对全部时间做处理&#xff0c;就存在问题了&#xff0c;网上看到两篇很详细的文章&#xff0c;记录下。 具体网址&…

Docker Elasticsearch安装ik分词插件教程

本章教程在通过Docker 安装Elasticsearch,并安装ik分词插件。本文的重点是安装ik分词插件。 一、安装Elasticsearch 安装教程以前写过,参考:https://blog.csdn.net/qq_19309473/article/details/140725121 安装之后,通过http://ip:9200,可以访问,就表示安装成功。 二、安装…

[python]socket之网络编程基础知识

1.三要素介绍: ip地址:设备在网络内的标识,分为ipv4和ipv6 端口号:软件(程序)在设备上的唯一标识.0-65535,其中0-1024为知名端口号,程序开发中最好不要使用 协议:数据发送的规则,有TCP和UDP 等 ip地址详解: 简单来说主要分为 IpV4, IpV6 IpV4: 采用4个字节, 十进制的形式来…

DSP基本名词术语及其关系

前言 信号处理是现代科技和工程领域中一个重要的分支&#xff0c;涉及对各种信号进行采集、传输、处理和分析的一系列方法和技术。其核心概念包括信号、系统、线性系统、时域与频域、稳定性和稳定性等。信号处理技术主要用于对模数转换后和数模转换前的数字信号进行处理&#x…

递归算法专题——真正理解递归和正确使用递归力扣实战应用

目录 1、使用递归 1.1 如何理解递归 1.2 如何写好一个递归算法 2、 算法应用【leetcode】 2.1 题一&#xff1a;汉诺塔问题【面试题】 2.1.1 算法原理 2.1.2 算法代码 2.2 题二&#xff1a;合并两个有序链表 2.2.1 算法原理 2.2.2 算法代码 2.3 题三&#xff1a;反转…

XC企业建站系统V1.2.5

多模板主题的企业官网建站系统。提供全部无加密源码&#xff0c;支持私有化部署。 V1.2.5添加小功能 站点配置&#xff0c;增加【留言板显示开关】 站点主题 - 扩展配置&#xff0c;增加对首页【产品中心】【新闻资讯】板块的显示开关和标题自定义功能&#xff08;注&#xff…

day-49 使数组中所有元素相等的最小操作数

思路 第一个数和最后一个数要变为一致&#xff0c;需要操作n-1次&#xff0c;然后第二个数和倒数第二个数要操作n-3次 解题过程 以此类推即可得出答案 Code class Solution {public int minOperations(int n) {int ans0;int t(n-1);while(t>0){anst;t-2;}return ans;} }作…

一、selenium自动化简介selenium工具集

文章目录 一、简介二、组成部分三、selenium工具集3.1 Selenium IDE3.2 Selenium WebDriver3.3 Selenium Grid3.4 Appium 一、简介 官方网站 Selenium 是支持 web 浏览器自动化的一系列工具和库的综合项目。 它提供了扩展来模拟用户与浏览器的交互&#xff0c;用于扩展浏览器分…

企业分享 - 益丰大药房监控升级之路

益丰大药房是全国大型药品零售连锁企业&#xff08;中国沪市主板上市连锁药房&#xff09;&#xff0c;专注医药零售行业23载&#xff0c; 市值稳居国内上市连锁药店前列/中国上市公司500强。 益丰有体量庞大的研发运维团队&#xff0c;有体量庞大的 IT 设施和服务&#xff0c;…