在分布式环境中使用状态机支持数据的一致性

news2024/11/18 6:45:07

简介

在本文中,我们将介绍如何在分布式系统中使用transaction以及分布式系统中transaction的局限性。然后我们通过一个具体的例子,介绍了一种通过设计状态机来避免使用transaction的方法。

什么是数据库transaction

Transaction是关系型数据普遍支持的一种操作。Transaction可以包含若干对数据库的操作。如果任何操作失败,所有的操作都被取消,数据保持transaction执行前的状态。这种情况叫回滚(rollback)。假如所有操作成功,transaction被认为成功。这种情况叫做提交(commit)。Transaction需要支持所谓的ACID。因为我们这种主要介绍NO-SQL数据库的transaction,ACID就不详细说了,如果不熟悉大家可以自行阅读。Transaction对于维护数据的完整性非常重要。比如说对于在两个银行账户之间的转账操作,从一个账户扣除金额和向一个账户增加金额就应该放在一个transaction里。否则只完成了扣除操作或者只完成增加操作,都会破坏数据的完整性,恢复起来非常麻烦。

No-SQL数据库的transaction

不少No-SQL数据库也支持transaction,但是普遍来说No-SQL数据库对transaction的支持相对较弱。主要原因是No-SQL数据库一般都是基于分布式的架构设计和实现的,而transaction的某些特性是和分布式系统有冲突的。比如说,在分布式系统中,我们往往放弃数据的强制一致性而追求整体系统的可用性。但是数据可能存在不一致的状态对于维护transaction的原子性和一致性是非常大的挑战。

我们在这里以AWS的DynamoDB为例。DDB支持两种transaction:写transaction和读transaction。写transaction可以支持最多100个写操作,包括put(创建),update(更新),delete(删除),和conditionCheck(条件检查)。而读transaction可以支持最多100个读操作,也就是通过primary key获取一个item,即Get。关于DDB的transaction的介绍可以参考这篇文档。

问题

现在我们在DDB中有四张表。表1保存了某种记录,该记录拥有自己的primary key,同时该记录还拥有3种其它的属性可以作为index。另外3张表即用来保存某种index到该记录的primary key的对应关系。关系如下所示:

需要说明的是每一种index都可能有多个值,也就是说在item里每种index都是一个list。比如说对于一个item,我们可能有3个index1,5个index2,10个index3。这样我们就要在index1表中创建3条记录,在index2表中创建5条记录,在index3中创建10条记录。很明显,我们需要保持item和它相关的index的完整性。也就是说我们不希望出现如下的情况:

  1. Index存在,但是其索引的item已经被删除了;
  2. Index存在,但是它已经不该索引到当前的item了;
  3. Item存在,但是它的某个index丢失了;
  4. 。。。

如果我们考虑使用DDB transaction来解决这个问题,我们会发现我们可能面临下面两个问题:

  • 一个item和它的索引数目大于100,所以DDB transaction无法支持该操作;
  • 因为有太多的数据要被一起更新,有很大的概率更新之间经常互相冲突,造成transaction的commit的成功率很低。

那么我们该如何解决这个问题呢?

解决方案

通过分析,我们发现这个问题其实可以通过设计一个简单的状态机来解决。我们将该方法的细节描述如下。

首先,我们规定在更新item和index时,我们遵循以下的顺序:

  1. 更新index1
  2. 更新index2
  3. 更新index3
  4. 更新item

如果我们其中任何一个步骤失败的话,我们就终止掉本次更新,并且抛出一个异常,然后根据设定在某段时间后重新尝试更新。根据我们执行的过程,我们可能会有如下的状态和状态转换:

最开始假设我们处于一个合法的状态下,也就是说item的RVN和index的RVN是相等的,都是n。然后我们更新index成功,此时我们处于一个临时状态下,也就是index的RVN变成了n+1,但是item的RVN仍然是n。再然后我们更新item成功,我们就转换成下一个合法的状态,也就是item的RVN和index的RVN再次相等,都变成了n+1。有一个例外的不合法状态,就是item的RVN已经变成了n+1,但是index的RVN仍然是n。出现这种状态的原因是这个index被从RVN为n+1的数据中移除出去了,那么此时这个index就不能再被认为是该item的合法索引了。

现在我们在更新数据时逻辑非常简单,我们不需要做很多的比较和检查,仅仅是依照顺序依次更新index和item即可。那么在使用该index查询item时,我们就需要做一些检查工作,确保我们是通过合法的index找到了合法的item。首先,我们需要一个index的值,来获取该index的RVN。然后我们通过该index获取item和item的RVN。然后我们检查的具体逻辑如下:

  1. 假如index的RVN和item的RVN相等,那么我们得到的index和item都是合法的;
  2. 假如index的RVN大于item的RVN,那么我们得到的是一个临时状态数据。我们可以抛出一个异常,然后重新尝试读取数据;
  3. 假如index的RVN小于item的RVN,我们是否可以直接认为数据不合法而放弃呢?是不可以的。原因在于有可能在我们得到index的RVN和得到item的RVN之间有过一次更新,从而使得我们已经有的index的RVN变旧了。所以我们要再次查询一次index的RVN,然后分成下面三种情况进行处理:
    1. 如果新的index的RVN仍然等于之前得到的index的RVN,说明是index被移除的情况,此时我们应该认为通过该index查询不到item;
    2. 如果新的index的RVN和item的RVN相等了,说明我们得到了合法的数据;
    3. 如果新的index的RVN和item的RVN仍然不相等,并且新的index的RVN和之前的index的RNV也不相等,说明我们得到的是一个中间状态的数据。我们可以抛出异常然后重新尝试查询。

通过这个处理逻辑,我们是可以完成保证没有任何合法的数据被遗漏,通过也不会有任何非法的数据被使用的。

结论和扩展

本文中,我们介绍了一种通过设计状态机以达到最终数据一致性的方法来避免使用transaction的方法。在这里我们看到两个问题:第一,在分布式环境中的transaction通过有一定的局限性,并且transaction本身运行的代价也很大,所以我们在决定使用transaction的时候还要经过和其它方法的比较,以及分析可能出现的局限性和问题;第二,基于数据的最终一致性,我们可能会发现其它更简单的方法以避免使用transaction。但是需要说明的是,这里并不是简单的建议不使用transaction。事实上,transaction在很多情况下是最佳解决方案。只是提供一个在使用transaction之外的其它代替方案。

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

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

相关文章

如何利用WebRTC构建点对点的即时通讯工具

在当今竞争激烈的商业环境中,企业越来越需要构建自己的即时通讯工具来提升内部沟通效率和信息安全,减少第三方工具依赖带来的潜在风险,并能与自身的行业业务深入融合。 拥有专用的通讯平台能够加快信息的流动,提升工作协同和任务执…

【C语言】【时间复杂度】Leetcode 153. 寻找旋转排序数组中的最小值

文章目录 题目时间复杂度概念时间复杂度的计算 解题思路代码呈现 题目 链接: link 时间复杂度 概念 时间复杂度是一种函数,定量地描述了该算法运行的时间。既然是一种函数,就涉及到自变量与因变量。因变量代表是时间复杂的规模,自变量是…

HTTP代理的特性、功能作用是什么样的?

在当今互联网时代,HTTP代理作为网络通信中的一项重要技术,在各行各业都有着广泛的应用。然而,对于许多人来说,HTTP代理的特性和功能作用并不十分清晰。在本文中,我们将深入探讨HTTP代理的各种特性和功能,帮…

Linux系统Docker部署Plik系统结合内网穿透实现公网访问本地文件

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问,实现随时随地在任意设备上传或者…

jenkins+maven+gitlab自动化构建打包、部署

Jenkins自动化部署实现原理 环境准备 1、jenkins已经安装好 docker安装jenkins 2、gitlab已经安装好 docker安装gitlab 一、Jenkins系统配置 1.Global Tool Configuration 任务构建所用到的编译环境等配置,配置参考: jdk配置(jenkins自带…

C# ListView 控件使用

1.基本设置 listView1.Columns.Add("序号", 60); //向 listView1控件中添加1列 同时设置列名称和宽度listView1.Columns.Add("温度", 100); //下同listView1.Columns.Add("偏移", 100);listView1.Columns.Add("分割", 50);listView1…

广州虚拟动力 | AI智能交互型虚拟数字人解决方案

广州虚拟动力整合自研的AI数字人技术与AI大语言模型技术,推出AI智能交互型虚拟数字人解决方案,面向旅游景区、博物馆、银行、医院、营业厅、酒店住宿、大型商场等,以AI数字人为载体,承担公共服务职能,根据各行业特性和…

学习Java的第十天

本章来讲一下什么是字符串 一、什么是字符串 在Java中,最常见的基本类型就是字符串了,哪哪都能见到,如输入语句,输出语句等!那么,什么是字符串呢,字符串就是String类,String类是Ja…

1361:产生数(Produce)

【解题思路】 1、将数字拆分保存在数组中,而后转换每一位。 2、将数字变化规则保存在x、y两个一维数组中,x[i]到y[i]是一种转换规则。 3、从n的初始值开始搜索,对n做数字拆分,将拆分后的各位数字保存在一个数组中。针对数组中的每…

使用timm库的一些知识点

timm(Torch Image Models)是一个在PyTorch上构建的图像模型库,它提供了一系列预训练的深度学习模型,使得研究人员和开发者可以方便地进行图像分类、目标检测等任务。 使用timm库创建模型时,如何确定模型的名字 使用…

3-14八股文学习

八股学习是看别人面试被问到的问题,然后把它发给GPT,让gpt讲一讲,自己再理解一下,真的很想拿offer,想去暑期实习啊啊啊啊啊 你用过什么 SpringBoot 里的什么注解?Spring Boot 中有很多常用的注解&#xff…

Ele admin pro和iView Admin pro的用户管理页面对比

Ele admin pro和iView Admin pro都是非常优秀的B端框架,功能大同小异,本文就着重比对一下二者的用户案例页面,让老铁们感知一些细节。 一、用户列表 用户列表 用户列表 二、用户编辑 三、用户添加 四、角色管理 五、权限分配 六、角色添加

Web前端开发学习路线图

Web前端开发学习路线图可以为你提供一个明确的学习路径,帮助你逐步掌握Web前端开发的各项技能。以下是一个基本的学习路线图,你可以根据自己的实际情况进行调整和补充。 一、基础阶段 HTML:学习HTML的基本语法,了解HTML文档的结构…

【Linux网络】应用层协议——http协议

目录 HTTP协议 认识URL urlencode和urldecode HTTP协议格式 HTTP请求协议格式 获取浏览器的HTTP请求 HTTP响应协议格式 构建HTTP响应给浏览器 构建处理HTTP请求类及代码完善 HTTP的方法 GET方法和POST方法 HTTP的状态码 HTTP常见Header Cookie&Session HTT…

c++ 常用函数 集锦 整理中

c 常用函数集锦 目录 1、string和wstring之间转换 1、string和wstring之间转换 std::string convertWStringToString(std::wstring wstr) {std::string str;if (!wstr.empty()){std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;str converter.to_b…

java 数据结构 优先级队列(PriorityQueue)

目录 优先级队列 堆的概念 堆的性质 堆的存储方式 堆的创建 堆的插入 堆的删除 用堆模拟实现优先级队列 PriorityQueue的特性 PriorityQueue常用接口介绍 堆排序 优先级队列 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下…

【BUG 弹药库】Tortoise git 绿色的勾 ✔ 和 红色的 !突然不见了该如何解决呢?

文章目录 1. 出现的问题描述如下所示&#xff1a;2. 如何解决这个问题呢 &#xff1f; 1. 出现的问题描述如下所示&#xff1a; 用 TortoiseGit 提交代码的时候&#xff0c;红色的 ! 和 绿色的 ✔ 突然消失了&#xff1b; 2. 如何解决这个问题呢 &#xff1f; ① 首先按住快…

新版Android Studio火烈鸟 在新建项目工程时 无法选java的语言模板解决方法

前言 最近下载最新版androidstudio时 发现不能勾选java语言模板了 如果快速点击下一步 新建项目 默认是kotlin语言模板 这可能和google主推kt语言有关 勾选1 如图所示 如果勾选 No Activity 这个模板 是可以选java语言模板的 但是里面没有默认的Activity 勾选2 和以前的用法…

SL6015B 耐压60V高调光比LED驱动IC 支持1.5A 输出30W功率

SL6015B是一款耐压60V、高调光比LED驱动IC&#xff0c;支持1.5A输出电流&#xff0c;最大输出功率达到30W。这款驱动IC专为LED照明应用而设计&#xff0c;具有出色的性能表现和广泛的应用前景。 首先&#xff0c;SL6015B的高耐压能力使其能够适用于各种高电压的LED照明场合。无…

如何免费获取基于公网 IP 的 SSL 证书 (无需域名)

现在给网站安装SSL证书来实现网站的HTTPS安全访问已经成了大多数人的共识&#xff0c;但是有一些特殊情况&#xff1a;比如对于个别的应用IP地址不需要绑定域名&#xff0c;只是单纯用IP来访问网站&#xff0c;这种情况下&#xff0c;可以实现HTTPS访问吗&#xff1f; 先说答案…