13 Redis-- 数据一致性模型、MySQL 和 Redis 的数据一致性

数据一致性模型

根据一致性的强弱分类,可以将一致性模型按以下顺序排列:

强一致性 > 最终一致性 > 弱一致性

数据一致性模型一般用于分布式系统中,目的是定义多个节点间的同步规范。

在这里,我们将其引入数据库和缓存组成的存储系统中,在这个系统中,数据库和缓存就是两个节点,我们将尝试采用不同的方案,实现这两个节点的同步状态。

强一致性模型

强一致性模型要求在分布式系统中,所有节点对于某个数据项的值都是一致的。
即:所有读操作总能返回最新的写操作结果。

强一致性模型可以通过使用共享内存原子操作同步机制来实现。

最终一致性模型

允许在分布式系统中,不同节点可能对于某个数据项的值是不一致的,但是在某个时间点,所有节点对于某个数据项的值都会达到一致。
即:读操作不一定能返回最新的写操作结果。数据更新后,不保证立即一致,但保证在一定时间内最终一致。

最终一致性模型通常使用消息队列事件源异步机制来解决数据一致性问题。

弱一致性模型

弱一致性模型允许在分布式系统中,不同节点可能对于某个数据项的值是不一致的。

弱一致性模型通常使用版本号(version number)最近COMMIT时间戳等机制来解决数据一致性问题。

区别

  • 强一致性与弱一致性的区别

强一致性要求在分布式系统中,所有节点对于某个数据项的值是一致的。弱一致性允许在分布式系统中,不同节点可能对于某个数据项的值是不一致的。强一致性可以通过使用共享内存、锁等同步机制来实现,而弱一致性可以通过使用版本号、时间戳等机制来解决数据一致性问题。

  • 最终一致性和弱一致性的区别

弱一致性允许在分布式系统中,不同节点可能对于某个数据项的值是不一致的。最终一致性允许在分布式系统中,不同节点可能对于某个数据项的值是不一致的,但是在某个时间点,所有节点对于某个数据项的值都会达到一致。最终一致性可以通过使用消息队列、事件源等异步机制来解决数据一致性问题。

强一致性模型适用于需要高度一致性的场景,如银行转账、电子商务订单等。

弱一致性模型适用于需要高度可用性和扩展性的场景,如缓存、数据备份等。

最终一致性模型适用于需要实时性和弹性的场景,如实时数据分析、日志处理等。在选择数据一致性模型时,需要权衡应用场景的一致性、可用性、扩展性和实时性需

MySQL 和 Redis 的数据一致性

 - 过程一致性- 第一种不一致:缓存和数据其中一者为空- 第二种不一致:缓存和数据皆存在,但值不同。- 
先抛一下结论:在满足实时性的条件下,不存在同时保证过程一致性和最终一致性的方案
最好的结果是第一种过程不一致 + 最终一致性方案。 

在满足实时性的前提下,不存在强一致性的方案,只有最终一致性方案。

事实上,除了秒杀余额交易等准确性要求高的业务外,其它业务并不追求强一致性。

在这里插入图片描述

不好的方案:每个请求都先写 MS,再写 Redis

例如 :A请求更新数据为10,B请求更新数据为11。最终 MS 和 Redis 中的变量应该都为 11。

至少应有四步,理想的顺序为

  1. 线程 A 执行 updateMySQL(10)。
  2. 线程 A 执行 updateRedis(10)。
  3. 线程 B 执行 updateMySQL(11)。
  4. 线程 B 执行 updateRedis(11)。

然而,As we all know:进程并发执行,其执行顺序并非固定。
理想的情况是 1234,但1324也是可能的。

最坏的情况,1342,即下图:
在这里插入图片描述
这种顺序下执行完四步,最终 MS 为 11;Redis 为 10。

不好的方案:每个请求都先写 Redis,再写 MS

与第一种方案出错的原因一致。
在这里插入图片描述

不好的方案:每个请求都先删除 Redis,再写 MS,最后写 Redis

这种方法可以达到最终 一致性,但可能由于过程不一致,被并发线程脏读。

请求 A 是更新请求,目标是将变量更新为 11
请求 B 是读请求
在这里插入图片描述
最初状态下:MS 和 Redis 都为 10。

  1. A请求第一步:删除缓存。此时 MS 为 10,缓存为空。
  2. B 查询变量的值,但是由于未命中缓存,查询 MS 得到 10。查询结果错误
  3. A请求第二步:更新 MS 11。此时 MS 为 11,缓存为空
  4. B 知道缓存中不存在,但 MS 中有,自然会写回 Redis,此时 MS 为 11,Redis 为 10。此时数据已经不一致了,任意线程此时查询,会查到错误的 10
  5. A请求第三步:更新 Redis 11。此时 MS 为 11,Redis 为 11。

【2】和【4】都是可能的脏读发生时机,【2】发生的可能更大,因为查询远快于更新。

好的方案:【缓存双删】每个请求都先删除 Redis,再写 MySQL,再删除 Redis

这个方案是对 “先删除 Redis,再写 MySQL” 的升级,因为在后者,存在最终一致性问题。
既然最终 MS 和 Redis 不一致,那干脆把 Redis 重新删除即可,这个也是大家常说的“缓存双删”。

A请求为更新请求,目标是将变量更新为 11
B请求为读请求,查询变量的值
在这里插入图片描述
最初状态下:MS 和 Redis 都为 10。

  1. A请求第一步:删除 Redis 中的变量10。此时 MS 为 10, Redis 为空
  2. B 查询变量的值,但是由于未命中缓存,查询 MS 得到 10
  3. A请求第二步:写 MS 为 11。此时 MS 为 11,Redis 空
  4. B 知道缓存中不存在,但 MS 中有,自然会写回 Redis,此时 MS 为 11,Redis 为 10。
  5. A请求第三步:删除 Redis 中的变量 10。此时 MS 为 11,Redis 为 空。

【2】和【4】都是可能的脏读发生时机,【2】发生的可能更大,因为查询远快于更新。

尝试改进【延时双删】每个请求都先删除 Redis,再写 MySQL,再延时删除 Redis

回看上一个方案的字部分-- 即时序图的第四步、第五步。

需要注意,第四步和第五步必须依次执行。

倘若先第五步: A请求第三步:删除 Redis 中的变量 10。此时 MS 为 11,Redis 为 空。
再第四步:B 知道缓存中不存在,但 MS 中有,自然会写回 Redis,此时 MS 为 11,Redis 为 10。

连最终一致性也不能保证了!这就是一个很坏的方案。

为了确保第四步第五步依次执行,不妨在执行第五步前,主动休眠 A请求一段时间,以确保最后执行。
这就是延时的地方。

但也并非完美,因为延时的时机如果掌控不好仍然会被脏读。

继续改进 使用消息队列

既然休眠总体第五步:定时延时删除缓存,不一定好用。

将这一步加入加入消息队列中,执行异步串行化删除。
在这里插入图片描述

好的方案:每个请求都先写 MS,再删除 Redis

在这里插入图片描述
【2】是可能的脏读发生时机

此外,在满足以下两个条件时,这种方案还可能出现另一种意外:

  • 请求B开始查询时,缓存刚好自动失效;
  • 请求 B 从数据库查出 10,回写缓存的耗时,比请求 A 写数据库,并且删除缓存的还长。
    在这里插入图片描述
    此时完全乱套了,数据库中的是错误的数据。

但注意,这种情况发生的条件之一是:请求 B 从数据库查出 10 的耗时 + 请求B 回写缓存的耗时 > 请求 A 写数据库 + 请求A 删除缓存的耗时

不等式左右两边各有一次数据库 + 一次缓存,但我们显然可知,左边查数据库的耗时,是远小于右边写数据库的耗时的

因此这一条件很难满足,极端情况发生的概率很小。

先写 MySQL,通过 Binlog,异步更新 Redis

这种方案,主要是监听 MySQL 的 Binlog,然后通过异步的方式,将数据更新到 Redis,这种方案有个前提,查询的请求,不会回写 Redis。
在这里插入图片描述
这个方案,会保证 MySQL 和 Redis 的最终一致性,但是如果中途请求 B 需要查询数据,如果缓存无数据,就直接查 DB;如果缓存有数据,查询的数据也会存在不一致的情况。

所以这个方案,是实现最终一致性的终极解决方案,但是不能保证实时性。

定论

  • 先写 Redis,再写 MySQL

这种方案,我肯定不会用,万一 DB 挂了,你把数据写到缓存,DB 无数据,这个是灾难性的;
我之前也见同学这么用过,如果写 DB 失败,对 Redis 进行逆操作,那如果逆操作失败呢,是不是还要搞个重试?

  • 先写 MySQL,再写 Redis

对于并发量、一致性要求不高的项目,很多就是这么用的,我之前也经常这么搞,但是不建议这么做;
当 Redis 瞬间不可用的情况,需要报警出来,然后线下处理。

  • 先删除 Redis,再写 MySQL

这种方式,我还真没用过,直接忽略吧。

  • 先删除 Redis,再写 MySQL,再删除 Redis

这种方式虽然可行,但是感觉好复杂,还要搞个消息队列去异步删除 Redis。

  • 先写 MySQL,再删除 Redis

比较推荐这种方式,删除 Redis 如果失败,可以再多重试几次,否则报警出来;
这个方案,是实时性中最好的方案,在一些高并发场景中,推荐这种。

  • 先写 MySQL,通过 Binlog,异步更新 Redis

对于异地容灾、数据汇总等,建议会用这种方式,比如 binlog + kafka,数据的一致性也可以达到秒级;
纯粹的高并发场景,不建议用这种方案,比如抢购、秒杀等。

个人结论:

实时一致性方案:采用“先写 MySQL,再删除 Redis”的策略,这种情况虽然也会存在两者不一致,但是需要满足的条件有点苛刻,所以是满足实时性条件下,能尽量满足一致性的最优解。
最终一致性方案:采用“先写 MySQL,通过 Binlog,异步更新 Redis”,可以通过 Binlog,结合消息队列异步更新 Redis,是最终一致性的最优解。

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

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

相关文章

【正点原子K210连载】第十四章 按键输入实验 摘自【正点原子】DNK210使用指南-CanMV版指南

1)实验平台:正点原子ATK-DNK210开发板 2)平台购买地址https://detail.tmall.com/item.htm?id731866264428 3)全套实验源码手册视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban 第十四章 按键输入实…

Vue3 登录成功,浏览器存在toke,再次访问/login路由到/index 首页页面

文章目录 目录 文章目录 流程 小结 概要流程技术细节小结 概要 首先需要清楚知道浏览器localstorage和Session storage的区别 localStorage 和 sessionStorage 是 HTML5 提供的两种客户端存储数据的方法,它们在使用和生命周期上有一些区别: 1. 生命周期…

@Cacheable解决复杂对象形参导致的缓存失效问题(如Map参数)

在Spring中使用 Cacheable 注解可以非常方便地实现方法的自动缓存机制。如以下代码: Cacheable(value "YwtbToken", key "#p0") public String createToken(String dlzh) {...}但当Cacheable 注解修饰的方法参数使用了复杂对象,如…

物联网数据可视化利器:云组态设计器全新升级

数据可视化已成为数据展示与分析领域非常重要的工具。由多种图表、3D图形组成的大屏能够帮助用户非常直观简洁地了解数据。在物联网环境下,用户在制作数据展示大屏时,对数据可视化工具提出了更高的要求,例如能够展示3D组件、灵活的图层结构、支持多种数据源、实时的数据更新、图…

函数创建单链表---无n型,需要 while 循环 + scanf

题目&#xff1a; #include <stdlib.h> struct link{int data;struct link *next; }; struct link* creatLink(); int main(){struct link *head,*p;headcreatLink();for(phead->next ;p;pp->next )printf("%d ",p->data );return 0; }/* 请在这里填…

软考《信息系统运行管理员》-2.1信息系统运维的管理

2.1信息系统运维的管理 信息系统运维管理体系框架 信息系统运维管理主要流程的目标 标准化&#xff1a;通过流程框架&#xff0c;构件标准的运维流程流程化&#xff1a;将大部分运维工作流程化&#xff0c;确保工作可重复&#xff0c;并且这些工作都有质量的完成&#xff0c;…

线性代数|机器学习-P20鞍点和极值

文章目录 1 . 瑞利商的思考1.1 瑞利商的定义1.2 投影向量 2. 拉格朗日乘子法3. 鞍点4. 线性拟合4.1 范德蒙矩阵线性拟合4.2 python 代码4.3 范德蒙矩阵缺点 5. 均值和方差5.1 样本均值和方差5.2 总体期望 μ \mu μ,总体方差 σ 2 \sigma^2 σ2 1 . 瑞利商的思考 1.1 瑞利商…

MySQL学习(6):SQL语句之数据控制语言:DCL

DCL用来管理数据库用户&#xff0c;控制数据库的访问权限 1.管理用户 1.1查询用户 use mysql; select * from user; #用户信息都存放在系统数据库mysql的user表中 在user表中&#xff0c;一个用户是由用户名和主机名共同决定的&#xff0c;上图中的host一栏就是用户的主机名…

常用组件详解(二):torchsummary

文章目录 一、基本使用二、常见指标2.1Input size2.2Forward/backward pass size 一、基本使用 torchsummary库是一个好用的模型可视化工具&#xff0c;用于帮助开发者把握每个网络层级的细节&#xff0c;包括其中的连接和维度。使用方法&#xff1a; from torchsummary impor…

ubuntu 安装docker

目录 docker 打包与加载 加载 Docker 镜像&#xff1a; ubuntu 安装docker 系统版本 检查卸载老版本docker 安装步骤 运行docker docker 打包与加载 打包成 .tar 文件&#xff1a; tar -cvf my-docker-image.tar * 加载 Docker 镜像&#xff1a; docker load -i my-d…

Access Levels in Swift

Access Levels (访问级别) Swift provides six different access levels for entities(实体) within your code. These access levels are relative to the source file in which an entity is defined, the module(模块) that source file belongs to, and the package that …

分享一个超级实用的东西——巴比达远程访问

前言 &#x1f388;家人们&#xff0c;今天我要和你们分享一个超级实用的东西——巴比达远程访问&#xff01;&#x1f389; &#x1f4bb;有了它&#xff0c;无论你身在何处&#xff0c;都能轻松访问家中的电脑&#x1f4bb;&#xff0c;就像在身边一样方便&#xff01;&…

短视频电商源码如何选择

在数字时代的浪潮下&#xff0c;短视频电商以其直观、生动、互动性强的特点&#xff0c;迅速崛起成为电商行业的一股新势力。对于有志于进军短视频电商领域的创业者来说&#xff0c;选择一款合适的短视频电商源码至关重要。本文将从多个角度探讨如何选择短视频电商源码&#xf…

携程礼品卡能转出去吗?

携程的卡好像只能在旅游的时候用 像买车票啊&#xff0c;机票啊&#xff0c;酒店&#xff0c;景点门票啥的&#xff0c;但是如果我没有出游计划的话 这个卡是不是就要被闲置下来&#xff1f; 这个问题一直让我感到很苦恼&#xff0c;还好有收卡云&#xff0c;不然我的携程卡…

模型部署:C++libtorch实现全连接模型10分类和卷积模型ResNet18的四分类的模型部署推理

Clibtorch实现模型部署推理 模型 全连接模型&#xff1a;公开mnist手写识别数字的十分类卷积模型&#xff1a;自行采集的鲜花四分类 部署 语言环境&#xff1a;C 对比Python python是解释性语言&#xff0c;效率很慢&#xff0c;安全性很低 系统开发一般是java、C/C&…

在 CentOS 上安装 Docker Engine

前言 Docker 是啥之类的就不必多说了&#xff0c;直接上安装步骤。 官网安装教程地址&#xff1a;https://docs.docker.com/engine/install/centos/ 1.Uninstall old versions &#xff08;卸载旧版本&#xff09; Older versions of Docker went by docker or docker-engin…

NLP特征提取的惊人历史演变

NLP特征提取的惊人演变 1.理解特征提取2. 文本表示的演变2.1.词袋的简单性2.2. N-Gram 模型的进步2.3. TF-IDF 的崛起 3. 深入研究词嵌入3.1.探索 Word2Vec3.2.深入了解 GloVe3.3.深入研究 FastText 4. 上下文嵌入的影响4.1 ELMo 的突破4.2 理解 BERT 的机制4.3 Transformer的出…

44 - 50题高级字符串函数 / 正则表达式 / 子句 - 高频 SQL 50 题基础版

目录 1. 相关知识点2.例子2.44 - 修复表中的名字2.45 - 患某种疾病的患者2.46 - 删除重复的电子邮箱2.47 - 第二高的薪水2.48 - 按日期分组销售产品2.49 - 列出指定时间段内所有的下单产品2.50 - 查找拥有有效邮箱的用户 1. 相关知识点 相关函数 函数含义concat()字符串拼接upp…

Ollama中文版部署

M1部署Ollama Ollama中文网站: Featured - 精选 - Ollama中文网 下载网址: Download Ollama on macOS 安装后运行llma3模型: ollama run llama3:8b 界面使用: GitHub - open-webui/open-webui: User-friendly WebUI for LLMs (Formerly Ollama WebUI) 部署open-webui: do…

烟台网站建设前需要了解哪些

在进行烟台网站建设之前&#xff0c;需要了解以下几个重要的方面&#xff1a; 1. 目标和定位&#xff1a;在建设网站之前&#xff0c;需要明确网站的目标和定位。是为了展示公司业务&#xff0c;还是为了销售产品&#xff0c;或者是为了提供信息和服务等。根据不同的目标和定位…