【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据缓存不一致分析)

一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据缓存不一致问题分析)

  • 数据不一致的原因
    • 逻辑失败导致的数据不一致
    • 物理失败导致的数据不一致
  • 数据一致性的解决方案
    • 消费消息异步删除缓存
      • 主要流程如下图所示
    • 订阅Binlog
    • 利用队列串行化
      • 具体分析
        • 存在的问题
        • 最终一致性
  • 彩蛋案例

数据不一致的原因

在引入缓存后,数据就会分散在两个不同的数据源中。由于数据的更新是实时的,因此很难保持数据的一致性,除非采用强一致性方案。在探索适当的解决方案之前,我们需要分析导致数据不一致的主要原因,并针对性地解决这些问题:
在这里插入图片描述

逻辑失败导致的数据不一致

之前我们详细分析了三种更新策略。在并发的情况下,无论是先删除缓存再更新数据库,还是先更新数据库再使缓存过期,都可能导致数据不一致的情况。这主要是因为在并发操作下,异步读写请求的时序可能导致了数据不一致,我们将其称为“逻辑失败”。解决这种由并发操作时序导致的问题的核心思想是将异步操作串行化执行。

物理失败导致的数据不一致

Cache Aside 模式中,先更新数据库再删除缓存以及异步双删策略等在同一个事务中,通常情况下,当使用分布式缓存时,如果缓存服务耗时较长,将更新数据库和使缓存失效操作放在同一个事务中,会导致大量的数据库连接挂起,严重降低系统性能,甚至可能因为数据库连接数过多而导致系统崩溃。这种由于缓存操作失败而导致的数据不一致称为"物理失败"。大多数情况下,我们会采用重试的方式解决物理失败的情况。

数据一致性的解决方案

  • 物理失败导致的数据不一致:在绝大部分业务场景中,我们通常追求的是最终一致性。为了解决因物理失败而导致的数据不一致,常见的解决方案包括消费消息异步删除缓存和订阅Binlog。

  • 逻辑失败导致的数据不一致:而对于逻辑失败导致的数据不一致,常用的解决方案则是通过队列实现异步操作的同步化。
    在这里插入图片描述

消费消息异步删除缓存

当涉及到消费消息异步删除缓存时,需要考虑数据一致性的问题。在这种情况下,如果缓存的删除操作是在消息消费后异步进行的,那么存在以下两种可能的数据一致性问题:

消息处理失败导致的数据不一致:如果消息消费过程中发生了错误,导致缓存删除操作未能正确执行,数据就会出现不一致。为了解决这个问题,可以采取一些措施,如记录消费状态、定期检查未完成的消息、重试消费等。

延迟删除导致的数据不一致:由于异步删除缓存的操作通常需要一定的时间,因此在缓存删除完成之前,可能会出现查询时获取到已经被删除的数据的情况。这种延迟删除可能会导致短暂的数据不一致。为了解决这个问题,可以采用一些方法,如使用合适的缓存过期时间、添加版本控制或标记来跟踪数据更新状态等。

主要流程如下图所示

在这里插入图片描述

为了确保数据一致性,可以考虑以下几点建议:

使用事务:如果可能的话,在消费消息和删除缓存的操作之间使用事务,确保它们要么都成功,要么都失败。这可以减少数据不一致的可能性。

监控和日志记录:设置监控机制来检测消息消费和缓存删除的状态,并记录日志以便排查问题和进行故障恢复。

定期校验和修复:定期检查数据一致性,并在发现问题时进行修复。可以编写一些脚本或工具来扫描数据并修复不一致性。

综上所述,要确保消费消息异步删除缓存的数据一致性,需要采取适当的措施来处理潜在的问题,并实施监控和修复机制来确保数据的准确性和一致性。

订阅Binlog

主要流程如下图所示:
在这里插入图片描述

利用队列串行化

在分析缓存旁路模式(cache aside pattern)时,我们发现在高并发情况下可能会发生数据不一致的情况,尽管这种情况发生的概率很低。

此外,在并发读写的情况下,如果我们先删除缓存再更新数据库,也可能导致数据不一致的问题。这些问题都是由于并发时序导致的,即写请求还未完成时,读请求就会读取到旧数据。

然而,如果我们能够确保请求的处理能够串行化,即读请求在写请求之后处理,那么就能保证读请求能够读取到最新的数据,从而避免数据不一致的问题。综上所述,我们在处理数据一致性的问题时需要考虑并发场景下请求处理的时序关系。

具体分析

采用队列将请求进行串行化。每个队列只对应一个工作线程。对于更新数据的写请求,我们将其放入队列中,等待异步处理;对于读请求,如果可以从缓存中获取数据,则直接返回;如果缓存中没有数据,我们将读请求放入队列中,等待写请求完成数据更新后再处理。

存在的问题

在这里插入图片描述

  • 读请求长时间阻塞:确实,如果队列中有多个写请求,读请求可能会长时间阻塞。为了解决这个问题,可以设置一个适当的超时时间,并在超时后直接从数据库中读取数据返回。这可以确保系统在高并发情况下的响应性。同时,在进行压力测试时,应注意队列中累积的写请求数量,如果积压过多,可以考虑队列的优化措施或相应解决方案。

  • 多个队列分散压力:是的,通过根据数据项进行哈希等路由方式,创建多个队列并行执行可以提高系统的吞吐量。这样可以将负载均衡到多个队列上,降低单个队列的压力,从而提高整体性能。

  • 操作复杂需要考虑全面:确实,将请求进行串行化通过队列是一种有效的数据一致性方案,但也需要考虑到队列的可用性、阻塞情况以及容灾恢复策略等问题。确保队列的稳定性和可靠性非常重要,尽量避免单点故障,并建立相应的容灾方案。

最终一致性

除了提到的三种通用方法,为缓存设置过期时间并定期进行全量同步也是一种接近最终一致性的简单有效方式。通过设置合理的过期时间,可以在缓存中保持数据的一致性,并定期进行全量同步,以确保缓存中的数据与数据库中的数据保持一致。这种方法可以在一定程度上提高系统的性能,并减少对队列串行化的依赖。

总结而言,选择适合业务场景的技术方案非常重要。在决策时,请综合考虑系统性能、数据一致性要求以及资源的限制,并进行权衡和优化。

彩蛋案例

在这里,我向大家推荐一本关于JVM优化和调优的实战系列书籍,《深入浅出Java虚拟机 — JVM原理与实战》。这本书是最新出版的,内容涵盖了与我们当前工作和开发实例密切相关的技术和实战案例。通过学习这本书,我们可以深入了解Java虚拟机的原理,并通过实践掌握优化和调优的技巧。我诚挚地推荐这本书给大家,相信它将为我们的工作和技术发展带来巨大的收益。希望大家能够抽出时间多多学习一下这本宝贵的资料
在这里插入图片描述
【当当-点击链接】【京东-点击链接】

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

盘口策略 | 交易中最重要的是什么?

量化策略开发,高质量社群,交易思路分享等相关内容 『正文』 ˇ 交易中最重要的是什么? 当然是Timing啊~~~ “时机是这个世界上最难得到,又最容易失去的东西”夫难得而易失者,时也;时至而不旋踵者,机也,故圣人常顺时…

VScode中的插件

开启VScode中最简单的内部浏览器 - 可以访问外网 - Browser Preview 插件安装: 插件使用:由下角 - 状态栏 - VS Browser按钮 live sass compiler-vscode插件将scss编译为css live sass compiler是VSCode扩展,可以实时地将SASS / SCSS文件…

【uniapp】学习之【生命周期】

uniapp生命周期 uni-app框架的生命周期分为两种 : 应用中的生命周期 和 页面内的生命周期 uni-app 应用生命周期 uni-app 页面生命周期

node.js使用nodemailer发送阿里云企业邮箱的邮件

百度一搜就能搜到各种博客例子,但是有个问题:有些参数写的不明不白的,我在发送的时候总是报错 后面看到了一篇博客: 基于nodemailer使用阿里云企业邮箱发送邮件(526错误的解决) 注意几点: …

智能汽车时代,产业如何“软硬兼施”

摘要: 智能汽车时代,以车用芯片、基础软件为代表的卡脖子关键技术,牵动着国内整个汽车供应链的安全。“软硬兼施”正成为从企业到汽车全行业的共同重大行动。 汽车产业链、供应链安全问题近两年已经引起全行业前所未有的关注。进入智能汽车时…

Nginx负载均衡、虚拟主机

目录 常用的6种负载均衡算法 轮询算法(round robin)默认 权重(weight) 响应时间(fair) 连接数(least_conn) IP_hash url_hash(第三方) 开发优选:一致性哈希 安装步骤: 虚拟主机 常用的6种负载均衡算法 轮询算法(round robin)默认 轮询方式&a…

uniapp 移动端 后台返回数据流 查看PDF

使用步骤&#xff1a; 1.官网下载地址pdf.js 2.在项目的根目录新建hybrid文件夹&#xff0c;将下载的pdf.js压缩包解压后&#xff0c;复制到hybrid下的html文件夹中 3.在page文件夹下新建一个filePreview.vue页面&#xff0c;页面代码如下&#xff1a; <template><…

让浮动元素在一行显示

&#x1f4dd;个人主页&#xff1a;爱吃炫迈 &#x1f48c;系列专栏&#xff1a;HTMLCSS &#x1f9d1;‍&#x1f4bb;座右铭&#xff1a;道阻且长&#xff0c;行则将至&#x1f497; <div class"wrap"><div class"item">1</div><di…

java项目之疫情期间医院门诊管理系统ssm源码+文档

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的疫情期间医院门诊管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风…

网络协议与攻击模拟-15-DNS协议

DNS 协议 1、了解域名结构 2、 DNS 查询过程 3、在 Windows server 上部署 DNS 4、分析流量 实施 DNS 欺骗 再分析 一、 DNS 1、概念 ● DNS ( domain name system &#xff09;域名系统&#xff0c;作为将域名的 IP 地址的相互映射关系存放在一个分布式的数据库&#xff0…

adb 常用命令解析

查询设备列表 adb devices 安装应用app adb install xx.apk 卸载应用app adb uninstall [-k] 查看安装的app包名 adb shell pm list packages 查看前台 Activity adb shell dumpsys activity activities | grep mFocusedActivity 查看当前正在运行的APK的包名 adb shell dumpsy…

BlazorServer非鉴权的登录和注册

BlazorServer入门 简单的登录与注册的设计 &#x1f383; 前言&#xff1a; 为了简单起见&#xff0c;本文不采用Autherize标签等直接可用的工具来实现登录和注册的设计。 现创建一个BlazorServer模板,使用的.Net Core版本为3.1。 &#x1f3ab;Blazor需要创建页面(组件)时请直…