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

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.mzph.cn/news/27947.shtml

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

相关文章

BL302嵌入式ARM控制器进行SQLite3数据库操作的实例演示

本文主要讲述了在钡铼技术BL302嵌入式arm控制器上运行 SQLite3 数据库的命令示例。SQLite3 是一个轻型的嵌入式数据库,不需要安装数据库服务器进程,占用资源低且处理速度快。 首先,需要将对应版本的 SQLite3 文件复制到设备的 /usr/ 目录下&…

c++开发模式,享元模式

享元模式&#xff0c;个人理解&#xff0c;就是应用共享技术来减少类的对象创建&#xff0c;节省计算机资源消耗&#xff0c;而且能够减少维护成本 #include <iostream> #include <string> #include <vector>using namespace std;class Flyweight { public:…

python之prettytable库的使用

文章目录 一 什么是prettytable二 prettytable的简单使用1. 添加表头2. 添加行3. 添加列4. 设置对齐方式4. 设置输出表格样式5. 自定义边框样式6. 其它功能 三 prettytable在实际中的使用 一 什么是prettytable prettytable是Python的一个第三方工具库&#xff0c;用于创建漂亮…

【微信小程序】申请蓝牙、位置和数据库等相关权限

在小程序的app.json文件中配置requiredPermissions字段&#xff0c;并在其中添加相应的权限。 以下是一个示例app.json文件的配置&#xff0c;包括了蓝牙、位置和数据库等权限的申请&#xff1a; {"pages": ["pages/index/index"],"requiredPermiss…

后端开发4.Elasticsearch的搭建

使用docker安装 安装elasticsearch 拉取镜像 docker pull elasticsearch:7.17.0容器间建立通信,创建 elastic的网关 docker network create elastic 创建es容器【自启动】【虚拟机处理器数量至少两个】 docker run --restart=always -p 9200:9200 -p 9300:9300 -e "…

CI/CD持续集成持续发布(jenkins)

1.背景 在实际开发中&#xff0c;我们经常要一边开发一边测试&#xff0c;当然这里说的测试并不是程序员对自己代码的单元测试&#xff0c;而是同组程序员将代码提交后&#xff0c;由测试人员测试&#xff1b; 或者前后端分离后&#xff0c;经常会修改接口&#xff0c;然后重新…

【LeetCode 热题 100】图论 专题(bfs,拓扑排序,Trie树 字典树)

from&#xff1a; https://leetcode.cn/studyplan/top-100-liked/ bfs 具有 边权为1 的最短路性质 拓扑排序&#xff0c;入度 Trie树&#xff0c; 高效存储 字符串【见鬼&#xff0c;不知道为什么写错&#xff0c;需要掌握熟练度】 文章目录 200. 岛屿数量【dfs / bfs】994. 腐…

Linux学习之awk

awk多数情况下作为sed的补充使用&#xff0c;awk会对sed处理过的内容进行格式的调整并输出。awk处理“比较规范”的文件&#xff0c;使用方法比较像脚本文件&#xff0c;sed把比较不规范的文件处理成比较规范的文件。 awk有三部分组成&#xff1a; 输入数据前例程 BEGIN{} 主输…

【LeetCode】287.寻找重复数

题目 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 &#xff0c;返回 这个重复的数 。 你设计的解决方案必须 不修改 数组 nums…

Makefile

什么是 Makefile 一个工程中的源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c; Makefile文件定义了一系列的规则来指定哪些文件需要先编译&#xff0c;哪些文件需要后编 译&#xff0c;哪些文件需要重新编译&#xff0c;甚至于进行更复杂的功…

Android平台GB28181设备接入端如何实现多视频通道接入?

技术背景 我们在设计Android平台GB28181设备接入模块的时候&#xff0c;有这样的场景诉求&#xff0c;一个设备可能需要多个通道&#xff0c;常见的场景&#xff0c;比如车载终端&#xff0c;一台设备&#xff0c;可能需要接入多个摄像头&#xff0c;那么这台车载终端设备可以…

使用webpack插件webpack-dev-server 出现Cannot GET/的解决办法

问题描述 文档地址深入浅出webpack 使用 DevServer运行webpack&#xff0c;跑起来之后提示Cannot GET/&#xff1a; 解决方案&#xff1a; 查阅官方文档 根据目录结构修改对应的配置&#xff1a; 然后就可以成功访问&#xff1a;

【MongoDB】万字长文,命令与代码一一对应SpringBoot整合MongoDB之MongoTemplate

目录 一、导入依赖与配置信息 二、导入测试数据创建实体类 三、插入数据 1、Insert默认集合插入 2、Insert指定集合插入 3、Insert批量插入数据 4、save默认集合插入 5、save指定集合插入 6、insert与save的区别 四、修改数据 1、修改符合条件的第一条数据 2、全…

redis 原理 7:开源节流 —— 小对象压缩

Redis 是一个非常耗费内存的数据库&#xff0c;它所有的数据都放在内存里。如果我们不注意节约使用内存&#xff0c;Redis 就会因为我们的无节制使用出现内存不足而崩溃。Redis 作者为了优化数据结构的内存占用&#xff0c;也苦心孤诣增加了非常多的优化点&#xff0c;这些优化…

[PM]敏捷开发之Scrum总结

在项目管理中&#xff0c;不少企业和项目团队也发现传统的项目管理模式已不能很好地适应今天的项目环境的要求。因此&#xff0c;敏捷项目管理应运而生&#xff0c;本文将为大家介绍Scrum敏捷项目管理以及应用方法。 什么是Scrum敏捷项目管理 敏捷项目管理作为新兴的项目管理模…

Java后台生成ECharts图片,并以Base64字符串返回

前言 通过echarts的jar包&#xff0c;Java后台生成一张图片&#xff0c;并把图片插入到word中。关于word插图片的代码在下一章。 需要用到的工具PhantomJS,Echarts-convert.js,jquery.js,echarts.js。 1.PhantomJS 介绍 PhantomJS是一个不需要浏览器的富客户端。 官方介绍&…

[保研/考研机试] 猫狗收容所 C++实现

题目描述&#xff1a; 输入&#xff1a; 第一个是n&#xff0c;它代表操作序列的次数。接下来是n行&#xff0c;每行有两个值m和t&#xff0c;分别代表题目中操作的两个元素。 输出&#xff1a; 按顺序输出收养动物的序列&#xff0c;编号之间以空格间隔。 源代码&#xff…

用i18n 实现vue2+element UI的国际化多语言切换详细步骤及代码

一、i18n的安装 这个地方要注意自己的vue版本和i1n8的匹配程度&#xff0c;如果是vue2点几&#xff0c;记得安装i18n的8版本&#xff0c;不然会自动安装的最新版本&#xff0c;后面会报错哦&#xff0c;查询了下资料&#xff0c;好像最新版本是适配的vue3。 npm install vue-…

Attacks in NLP

一、 Introduction NLP对抗攻击是人工智能对抗攻击的一个重要的组成部分&#xff0c;但是最近几年才逐渐开始兴起&#xff0c;究其原因在于NLP对抗攻击与传统computer vision或者audio对抗攻击有很大的不同&#xff0c;主要在于值空间的连续性&#xff08;CV、audio&#xff0…

04-6_Qt 5.9 C++开发指南_QListWidget和QToolButton

文章目录 1. 实例简介2. 源码2.1 混合式界面设计2.2 mainwindow.h2.3 mainwindow.cpp 1. 实例简介 Qt 中用于项 (Item)处理的组件有两类&#xff0c;一类是 Item Views&#xff0c;包括 QListView、QTreeView、QTableView、QColumnView 等;另一类是 Item Widgets&#xff0c;包…