分布式协议与算法——CAP理论、ACID理论、BASE理论

news2024/11/22 17:47:17

CAP理论

CAP理论,对分布式系统的特性做了高度抽象,比如抽象成了一致性、可用性和分区容错性,并对特性间的冲突(也就是CAP不可能三角)做了总结。

CAP三指标

CAP理论对分布式系统的特性做了高度抽象,形成了三个指标:

  • 一致性(Consistency)
  • 可用性(Availability)
  • 分区容错性(Partition Tolerance)

一致性:指的是客户端的每次读操作,不管访问哪个节点,要么读到的都是同一份最新写入的数据,要么读取失败。

可用性:指的是任何来自客户端的请求,不管访问哪个非故障节点,都能得到响应数据,但不保证是同一份最新数据。这个指标强调的是服务可用,但不保证数据正确。

分区容错性:指的是当节点间出现任意数量的消息丢失或高延迟的时候,系统仍然在继续工作。也就是说,分布式系统在告诉访问本系统的客户端:不管我的内部出现了什么样的数据同步问题,我会一直运行。这个指标强调的是集群对分区故障的容错能力。

在分布式系统中,分区容错性是必须要考虑的。

CAP不可能三角

CAP 不可能三角说的是对于一个分布式系统而言,一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance)3 个指标不可兼得,只能在 3 个指标中选择 2 个。

如何使用CAP理论

只要有网络交互就一定会有延迟和数据丢失,而这种状况必须接受,还必须保证系统不能挂掉。所以节点间的分区故障是必然发生的。也就是说,分区容错性(P)是前提,是必须要保证的

那么剩下一致性(C)和可用性(A)可以选择了:要么选择一致性,保证数据正确;要么选择可用性,保证服务可用。

  • 当选择了一致性(C)的时候,一定会读到最新的数据,不会读到旧数据,但如果因为消息丢失、延迟过高发生了网络分区,那么这个时候,当集群节点接收到来自客户端的读请求时,为了不破坏一致性,可能会因为无法响应最新数据,而返回出错信息。
  • 当选择了可用性(A)的时候,系统将始终处理客户端的查询,返回特定信息,如果发生了网络分区,一些节点将无法返回最新的特定信息,它们将返回自己当前的相对新的信息。

许多人认为无论在什么情况下,分布式系统都只能在C和A中选择1个。其实在分布式系统正常运行时,就是说在不需要P时,C和A能够同事保证。只有当发生分区故障的时候,也就是说需要P时,才会在C和A之间做出选择。

小结

CA模型,在分布式系统中不存在。因为舍弃 P,意味着舍弃分布式系统,就比如单机版关系型数据库 MySQL,如果 MySQL 要考虑主备或集群部署时,它必须考虑 P。

CP模型,采用 CP 模型的分布式系统,舍弃了可用性,一定会读到最新数据,不会读到旧数据。一旦因为消息丢失、延迟过高发生了网络分区,就影响用户的体验和业务的可用性(比如基于 Raft 的强一致性系统,此时可能无法执行读操作和写操作)。典型的应用是 Etcd,Consul 和 Hbase。

AP模型,采用 AP 模型的分布式系统,舍弃了一致性,实现了服务的高可用。用户访问系统的时候,都能得到响应数据,不会出现响应错误,但会读到旧数据。典型应用就比如 Cassandra 和 DynamoDB。

在当前分布式系统开发中,延迟是非常重要的一个指标,比如,在 QQ 后台的名字路由系统中,通过延迟评估服务可用性,进行负载均衡和容灾;再比如,在 Hashicorp/Raft 实现中,通过延迟评估领导者节点的服务可用性,以及决定是否发起领导者选举。所以,在分布式系统的开发中,需要意识到延迟的重要性,能通过延迟来衡量服务的可用性。

ACID理论

ACID理论可以看成是对事务特性的抽象和总结,方便实现事务。可以理解为:如果实现了操作的ACID特性,那么就实现了事务。在单机上实现事务并不难,如可以通过锁、时间序列等机制保障操作的顺序执行,让系统实现ACID特性。但在分布式系统中比较困难,因为分布系统涉及多个节点间的操作。加锁、时间序列等机制,只能保证单个节点上的ACID特性,无法保证节点间操作的ACID特性。

通过分布式事务协议,如二阶段提交协议和**TCC(Try-Confirm-Cancel)**可以实现分布式系统上的ACID特性。

问题:

如何保证节点A、B、C执行分布式事务操作X,要么全部执行,要么全部不执行。

二阶段提交协议

二阶段提交协议(2pc),就是通过二阶段的协商来完成一个提交操作,具体的操作如下:

客户端发送消息给节点A,节点A收到消息后就扮演协调者(Coordinator)的身份,由节点A通信节点B和节点C,发起二阶段提交。

第一阶段为提交请求节点(又称投票阶段)。首先节点A向节点B和节点C发送消息:“能否执行操作X”,节点B和节点C判断 能否执行操作X,如果可以就预留一部分资源给操作X。最后将能否执行操作X发送给节点A,节点A收到全部的回复结果(包括自己的结果),这里假设全都是能够执行的回复。

第二阶段为提交执行阶段(又称完成阶段),也就是执行具体的操作了。首先节点A按照要么全部执行,要么全部放弃的原则,统计回复结果,由于所有的回复结果都是能够执行,所以节点A决定执行分布式事务操作X。然后通知节点B、节点C执行操作X。节点B和节点C在收到通知后,执行事务操作X。最后节点B和节点C将执行事务的结果返回给节点A。

在第一个阶段中,每个节点决定是放弃还是提交,一旦参与者决定提交事务,那么就不允许放弃事务。也就是说,在一个节点决定提交事务之前,它必须保证能够执行事务操作,即使出现故障或者中途被替换掉。

在第二个阶段中,事务的每个参与节点执行最终统一的决定,提交或者放弃事务。这个约定,实现了ACID中的原子性。

二阶段提交协议最早时用来实现数据库的分布式事务的,不过现在常用的协议是XA协议,该协议是基于二阶段提交协议提出的。不管是原始的二阶段提交协议,还是XA协议,都存在一些问题:

  • 在提交请求阶段,需要预留资源,在资源预留期间,其他人不能操作。。
  • 数据库是独立的系统。(数据库是独立的,也就是说数据库是独立的第三方软件,我们可以编程或修改业务代码,但很少会修改数据库核心代码,更不会根据业务需求修改实现不同的数据库代码逻辑。)

个人感觉2pc依赖每个数据库节点的事务。

TCC(Try-Confirm-Cancel)

TCC 是Try(预留)、Confirm(确认)、Cancel(撤销)3个操作的简称,它包含了预留、确认或撤销这2个阶段。

第一阶段为预留阶段。客户端通知节点A、节点B、节点C让它们预留执行操作X的相关资源,客户端实现确认操作(执行操作X)和撤销操作(取消执行操作X)。然后客户端收到节点A、节点B、节点C的预留答复,假设这里都是OK。

如果预留阶段的执行都没有问题,就进入确认阶段。客户端执行确认操作,通知节点A、节点B、节点C执行操作,客户端收到确认操作的响应后,完成分布式事务。

如果预留阶段出错,比如节点A无法执行操作X,那么就进入撤销阶段。客户端执行撤销操作,通知节点A、节点B、节点C取消执行操作X,客户端收到撤销操作的响应。

TCC本质上是补偿事务,它的核心思想是针对每个操作都要注册一个与其对应的确认操作和补偿操作(也就是撤销操作)。它是一个业务层面的协议,可以将TCC理解为编程模型,即TCC的三个操作都是在业务代码中编程实现的。为了实现一致性,确认操作和补偿操作必须是幂等的。这两个操作会失败重试。

TCC不依赖于数据库的事务(2pc应该是要依赖的),而是在业务中实现了分布式事务,这能减轻数据库的压力,但对业务代码的入侵性比较高,实现比较复杂。

ps:我感觉这点是与2pc不同的点吧,还有2pc是有一个节点作为协调者,而TCC是由客户端作为协调者。

小结

二阶段提交协议和TCC是实现分布式系统ACID特性的方法

  1. 二阶段提交协议,不仅仅是协议,也是一种非常经典的思想。二阶段提交在达成提交操作共识的算法中应用广泛,比如 XA 协议、TCC、Paxos、Raft 等。
  2. 幂等性,是指同一操作对同一系统的任意多次执行,所产生的影响均与一次执行的影响相同,不会因为多次执行而产生副作用。常见的实现方法有 Token、索引等。它的本质是通过唯一标识,标记同一操作的方式,来消除多次执行的副作用。

可以将 ACID 特性理解为 CAP 中一致性的边界,最强的一致性。根据 CAP 理论,如果在分布式系统中实现了一致性,可用性必然受到影响。比如,如果出现一个节点故障,则整个分布式事务的执行都是失败的。实际上,绝大部分场景对一致性要求没那么高,短暂的不一致是能接受的,另外,也基于可用性和并发性能的考虑,在开发实现分布式系统,如果不是必须,尽量不要实现事务,可以考虑采用最终一致性。

BASE理论

BASE 理论是 CAP 理论中的 AP 的延伸,是对互联网大规模分布式系统的实践总结,强调可用性。

BASE理论的核心是基本可用(Basically Available)和最终一致性(Eventually consistent)。还有一种过度状态—软状态(Soft state),软状态描述的是实现服务可用性的时候系统数据的一种过度状态,也就是说不通节点间,数据副本存在短暂的不一致。

实现可用的4种方式

  • 流量削峰:例如12306订票系统,可以在不同的时间,出售不同区域的票,将访问请求错开,消弱请求峰值。
  • 延迟响应:将购票请求在队列中进行排队,过段时间在进行处理。
  • 体验降级:如使用小图片代替原始图片,通过降低图片的清晰度和大小,提升系统的处理能力。
  • 过载保护:把接收到的请求放在指定的队列中排队处理,如果请求等待时间超时了(假设是 100ms),这个时候直接拒绝超时请求;再比如队列满了之后,就清除队列中一定数量的排队请求,保护系统不过载,实现系统的基本可用。

最终一致性

最终一致性是说,系统中所有的数据副本在经过一段时间的同步之后,最终能够达到一个一致的状态。在数据一致性上,存在一个短暂的延迟。

那么如何实现最终一致性? 首先确定它以什么为准,因为这是实现最终一致性的关键。一般来说,工程实践中有如下几种方式:

  • 以最新写入的数据为准,比如 AP 模型的 KV 存储采用的就是这种方式(就是最新的数据);
  • 以第一次写入的数据为准,如果你不希望存储的数据被更改,可以以它为准(就是一次写入后面不会修改了)。

常见的实现最终一致性的具体方式如下:

  • 读时修复:在读取数据时,检测数据的不一致,进行修复。比如 Cassandra 的 Read Repair 实现,具体来说,在向 Cassandra 系统查询数据的时候,如果检测到不同节点的副本数据不一致,系统就自动修复数据。
  • 写时修复:在写入数据,检测数据的不一致时,进行修复。比如 Cassandra 的 Hinted Handoff 实现。具体来说,Cassandra 集群的节点之间远程写数据的时候,如果写失败就将数据缓存下来,然后定时重传,修复数据的不一致性。
  • 异步修复:这个是最常用的方式,通过定时检测副本数据的一致性,并修复(反熵的方式)。

写修复就是写的时候没有成功就将数据缓存下来,然后定时重传,保证数据写入成功。写修复不需要做数据一致性对比,性能消耗比较低,对系统运行影响不大。而读修复和异步修复需要做数据的一致性对比,性能消耗比较多。因此推荐写修复实现最终一致性。

小结

  1. BASE 理论是对 CAP 中一致性和可用性权衡的结果,它来源于对大规模互联网分布式系统实践的总结,是基于 CAP 定理逐步演化而来的。它的核心思想是,如果不是必须的话,不推荐实现事务或强一致性,鼓励可用性和性能优先,根据业务的场景特点,来实现非常弹性的基本可用,以及实现数据的最终一致性。
  2. BASE 理论主张通过牺牲部分功能的可用性,实现整体的基本可用,也就是说,通过服务降级的方式,努力保障极端情况下的系统可用性。
  3. ACID 理论是传统数据库常用的设计理念,追求强一致性模型。BASE 理论支持的是大型分布式系统,通过牺牲强一致性获得高可用性。BASE 理论在很大程度上,解决了事务型系统在性能、容错、可用性等方面痛点。另外我再多说一句,BASE 理论在 NoSQL 中应用广泛,是 NoSQL 系统设计的事实上的理论支撑。

参考

  • 分布式协议与算法实战 学习笔记

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

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

相关文章

境内金融信息服务报备33家机构名单

2022年01月04日,国家互联网信息办公室关于发布第一批境内金融信息服务机构报备编号的公告,公开发布第一批20家金融信息服务机构的名称及报备编号。 2022年10月28日,国家互联网信息办公室关于发布第二批境内金融信息服务机构报备编号的公告&am…

Linux常用命令学习总结

Linux命令分类 1. Linux目录操作命令2. Linux文件名称3. Linux磁盘命令4. Linux进程与防火墙5. Linux用户与组的关系6. Linux权限操作(chmod命令)7. Linux中的文件类型文件的寻找 最近系统地学习下Linux命令的使用,因此作如下记录,以便随时复习和翻阅。 …

栈和队列的实现以及OJ题讲解

💓博主个人主页:不是笨小孩👀 ⏩专栏分类:数据结构与算法👀 刷题专栏👀 C语言👀 🚚代码仓库:笨小孩的代码库👀 ⏩社区:不是笨小孩👀 🌹欢迎大家三连关注&…

Android安卓实战项目(9)—漂亮的健身APP主页控件+开机动画+BMI计算(源码在文末)可用于比赛项目或者作业参考中

Android安卓实战项目(9)—漂亮的健身控件APP开机动画BMI计算(源码在文末🐕🐕🐕) 介绍: BMI(Body Mass Index,身体质量指数)是一种常用的健康指标…

Spring Cloud Alibaba (一)

1 微服务介绍 1.1 系统架构演变 随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。 从互联网早起到现在,系统架构大体经历了下面几个过程: 单体应用架构--->垂直应用架构--->分布 式架构--->S…

LeetCode 29题:两数相除

题目 给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.…

一生一芯1——windows与Ubuntu双系统安装

UltraISO下载 下载链接:https://pan.baidu.com/s/18ukDs6yL64qU6thYyZEo-Q?pwdo8he 提取码:o8he 一路傻瓜安装,安装后点击继续试用 Ubuntu系统下载 这里我使用的是官网的22.04版本,由于大于4G,无法上传至百度网盘…

【CSS】CSS 选择器

CSS 选择器 1.基础选择器 1.1 元素选择器 语法:标签名{...} 元素选择器会选中对应标签名的HTML元素,例如:p{...},div{...},span{...}等 1.2 类选择器 语法:.类名{...} 类选择器会选中class属性为指定…

老胡的周刊(第102期)

老胡的信息周刊[1],记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 🎯 项目 ChatGPT-Shortcut[2] ChatGPT 快捷指令&…

MyBatis-Plus是什么以及特性[MyBatis-Plus系列] - 第481篇

​ 悟纤:师傅,宝宝不开心呢。 师傅:怎么不开心? 悟纤:感觉好多重复的代码来着。 师傅:是哪个部分重复的代码来着? 悟纤:就是对于一个model的增删改查部分。 师傅:那这…

周赛357(模拟、脑经急转弯、多源BFS+并查集、反悔贪心)

文章目录 周赛357[2810. 故障键盘](https://leetcode.cn/problems/faulty-keyboard/)模拟双端队列O(n) [2811. 判断是否能拆分数组](https://leetcode.cn/problems/check-if-it-is-possible-to-split-array/)脑经急转弯 [2812. 找出最安全路径](https://leetcode.cn/problems/f…

SpringBoot系列---【三种启动传参方式的区别】

三种启动传参方式的区别 1.三种方式分别是什么? idea中经常看到下面三种启动传参方式 优先级 Program arguments > VM options > Environment variable > 系统默认值 2.参数说明 2.1、VM options VM options其实就是我们在程序中需要的运行时环境变量,它需…

实现Jenkins自动发包配置

参考抖音:Java不良人 其中的视频演示代码 不推荐把jenkins端口一直开放,推荐使用时候放开(版本不太新,避免漏洞攻击) [rootVM-4-12-centos soft]# docker-compose -v Docker Compose version v2.19.1docker-compose.…

TCP三次握手四次断开

一、了解TCP 🍅TCP :传输控制协议,是一种面向连接的可靠的传输协议。 什么是可靠的传输协议?如何保障可靠传输? 保证可靠性: 1.确认机制 2.重传输机制什么是面向连接?如何保障面…

C语言 | 位运算符>>的高级用法

一、人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 —— 自在。 第二位上场的是和我们一起学习的小白程序猿 —— 逍遥。 二、优化除法运算 除法运算需要比位移运算需要更多的计算资源,某些情况下采用位移运算可以提高性能 代码示例 #in…

代码随想录算法训练营第51天|动态规划part09|198.打家劫舍、213.打家劫舍II、337.打家劫舍III

代码随想录算法训练营第51天|动态规划part09|198.打家劫舍、213.打家劫舍II、337.打家劫舍III 198.打家劫舍 198.打家劫舍 思路: 仔细一想,当前房屋偷与不偷取决于 前一个房屋和前两个房屋是否被偷了。 所以这里就更感觉到&a…

VectorDBBench向量数据库性能评测工具

目录 一、背景和意义 二、特点和优势 三、应用场景和实际效果 四、总结 摘要: VectorDBBench.com是一个基于云计算的向量数据库基准测试平台,旨在评估不同向量数据库的性能和可扩展性。本文介绍了VectorDBBench的背景和意义,分析了VectorDBBench的特点和优势,并从多个方…

C# Atrribute和反射的简单例子

Attribute 需要以Attribute 结尾, 并继承Attribute namespace AttributeTest {public class HeroAttribute : Attribute{} }namespace AttributeTest {public class SkillAttribute : Attribute{} }namespace AttributeTest {[Hero]public class Blademaster{[Skill]public vo…

【PCB专题】Allegro中如何自动查找并删除不使用的规则

在Allegro软件使用中,我们经常是从上一个版本修改而来的。那么就会遇到有些多余规则没有使用的情况,怎么能够知道哪些规则没有使用并删除呢? 如下所示在Electrical中的All Constraints下存在SDIO规则和WIFI_SDIO规则。这两个规则是重复的,只是名称不同而已。 在规则的使…

前端工具类

日期类 1️⃣ 新建index.js文件/*** param {date} time 需要转换的时间* param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss*/ export function formatTime(time, fmt) {if (!time) {return "";}else {const date new Date(time);const o {M:…