网站设计宁波,网站样版风格排版,给医院做网站赚钱吗,购物商城类网站备案一致性模型本质上是进程与数据存储的约定#xff0c;通过一致性模型我们可以理解和推理在分布式系统中数据复制需要考虑的问题和基本假设。那么#xff0c;一致性模型的具体实现有一些呢#xff1f;本文会介绍一致性协议实现的主要思想和方法。
什么是一致性协议
一致性协…一致性模型本质上是进程与数据存储的约定通过一致性模型我们可以理解和推理在分布式系统中数据复制需要考虑的问题和基本假设。那么一致性模型的具体实现有一些呢本文会介绍一致性协议实现的主要思想和方法。
什么是一致性协议
一致性协议描述了特定一致性模型的实际实现。一致性模型就像是接口而一致性协议就像是接口的具体实现。一致性模型提供了分布式系统中数据复制时保持一致性的约束为了实现一致性模型的约束需要通过一致性协议来保证。
一致性协议根据是否允许数据分歧可以分为两种
单主协议不允许数据分歧整个分布式系统就像一个单体系统所有写操作都由主节点处理并且同步给其他副本。例如主备同步、2PC、Paxos 都属于这类协议。多主协议允许数据分歧所有写操作可以由不同节点发起并且同步给其他副本。例如 Gossip、POW。
可以发现它们的核心区别在于是否允许多个节点发起写操作单主协议只允许由主节点发起写操作因此它可以保证操作有序性一致性更强。而多主协议允许多个节点发起写操作因此它不能保证操作的有序性只能做到弱一致性。
值得注意的是一致性协议的分类方式有很多种主要是看从哪个角度出发进行归类常用的另一个归类方式是根据同步/异步复制来划分这里就不多做讨论了。下面对单主协议和多主协议分别做一些共性的分析篇幅所限不会深入到协议细节。
单主协议
单主协议的共同点在于都会用一个主节点来负责写操作这样能够保证全局写的顺序一致性它有另一个名字叫定序器非常的形象。
主备复制
主备复制可以说是最常用的数据复制方法也是最基础的方法很多其他协议都是基于它的变种。 主备复制要求所有的写操作都在主节点上进行然后将操作的日志发送给其他副本。可以发现由于主备复制是有延迟的所以它实现的是最终一致性。
主备复制的实现方式主节点处理完写操作之后立即返回结果给客户端写操作的日志异步同步给其他副本。这样的好处是性能高客户端不需要等待数据同步缺点是如果主节点同步数据给副本之前数据缺失了那么这些数据就永久丢失了。MySQL 的主备同步就是典型的异步复制。
两阶段提交
两阶段提交2PC是关系型数据库常用的保持分布式事务一致性的协议它也属于同步复制协议即数据都同步完成之后才返回客户端结果。可以发现 2PC 保证所有节点数据一致之后才返回给客户端实现了顺序一致性。
2PC 把数据复制分为两步
表决阶段主节点将数据发送给所有副本每个副本都要响应提交或者回滚如果副本投票提交那么它会将数据放到暂存区域等待最终提交。提交阶段主节点收到其他副本的响应如果副本都认为可以提交那么就发送确认提交给所有副本让它们提交更新数据就会从暂存区域移到永久区域。只要有一个副本返回回滚就整体回滚。
可以发现 2PC 是典型的 CA 系统为了保证一致性和可用性2PC 一旦出现网络分区或者节点不可用就会被拒绝写操作把系统变成只读的。由于 2PC 容易出现节点宕机导致一直阻塞的情况所以在数据复制的场景中不常用一般多用于分布式事务中注实际应用过程中会有很多优化。
分区容忍的一致性协议
分区容忍的一致性协议跟所有的单主协议一样它也是只有一个主节点负责写入提供顺序一致性但它跟 2PC 的区别在于它只需要保证大多数节点一般是超过半数达成一致就可以返回客户端结果这样可以提高了性能同时也能容忍网络分区少数节点分区不会导致整个系统无法运行。分区容忍的一致性算法保证大多数节点数据一致后才返回客户端同样实现了顺序一致性。
下面用一个简单的示例来说明这类算法的核心思想。假设现在有一个分布式文件系统它的文件都被复制到 3 个服务器上我们规定要更新一个文件客户端必须先访问至少 2 个服务器大多数得到它们同意之后才能执行更新同时每个文件都会有版本号标识要读取文件的时候客户端也必须要访问至少 2 个服务器获取该文件的版本号如果所有的版本号一致那么该版本必定是最新的版本因为如果前面的更新操作要求必须要有大多数服务器的同意才能更新文件。
以上就是我们熟知的 Paxos、ZAB、Raft 等分区容忍的一致性协议的核心思想一致性的保证不一定非要所有节点都保持一致只要大多数节点更新了对于整个分布式系统来说数据也是一致性的。上面只是一个简单的阐述真正的算法实现是比较复杂的这里就不展开了。
分区容忍的一致性协议如 Paxos 是典型的 CP 系统为了保证一致性和分区容忍在网络分区的情况下允许大多数节点的写入通过大多数节点的一致性实现整个系统的一致性同时让少数节点停止服务不能读写放弃整体系统的可用性也就是说客户端访问到少数节点时会失败。
值得注意的是根据 CAP 理论假设现在有三个节点 A、B、C当 C 被网络分区时有查询请求过来此时 C 因为不能和其他节点通信所以 C 无法对查询做出响应也就不具备可用性。但在工程实现上这个问题是可以被绕过的当客户端访问 C 无法得到响应时它可以去访问 A、B实际上对于整个系统来说还是部分可用性的并不是说 CP 的系统一定就失去可用性。详细的分析参考分布式系统CAP 理论的前世今生
多主协议
相比单主协议为了实现顺序一致性不允许多个节点并发写多主协议恰恰相反只保证最终一致性允许多个节点并发写能够显著提升系统性能。由于多主协议一般提供的都是最终一致性所以常用在对数据一致性要求不高的场景中。
Gossip 协议就是一种典型的多主协议很多分布式系统都使用它来做数据复制例如比特币作为一条去中心化的公链所有节点的数据同步都用的是 Gossip 协议。此外Gossip 协议也在一些分布式数据库中如 Dynamo 中被用来做分布式故障检测的状态同步当有节点故障离开集群时其他节点可以快速检测到。
从名称上就可以看出 Gossip 协议的核心思想Gossip 是流言八卦的意思想想我们日常生活人与人之间传八卦的场景在学校里面一个八卦一旦有一个人知道了通过人传人基本上整个学校的人最终都会知道了。因此 Gossip 协议的核心思想就是每个节点都可以对其他节点发送消息接收到消息的节点随机选择其他节点发送消息接收到消息的节点也做同样的事情。
多主协议允许运行多个节点并发写就一定会出现对一个数据并发写导致数据冲突的情况因此这类协议都需要解决并发写的问题。单主协议通过主节点控制写入保证不会出现并发写的情况因为所有写操作最终都会通过主节点排序从某种意义上讲使用单主协议的系统对于写入实际上是串行的因此其性能是有瓶颈的。而多主协议允许多节点并发写提搞了写入的性能但是实际上它是把数据合并的操作延迟了单主协议在写入的时候就进行了数据合并因此读取数据的时候如果出现数据冲突的时候就需要对数据进行合并保证全局一致性。
前面我们提到比特币使用的是 Gossip 协议做数据复制那么问题来了不是说多主协议性能会比较高吗为什么比特币的性能那么差这里实际上要分开来看由于比特币是去中心化的但是它的支付功能需要保证全局数据一致性因此它用了一种很巧妙的一致性算法 POW所有节点都做一道数学题谁先算出答案谁有权利将交易写到链上然后利用 Gossip 协议传播它的答案和交易其他节点验证它的答案正确就将数据保存起来。
到这里你可能会有一个疑问POW 作为多主协议为什么性能这么低任何协议都有它适用的场景。在比特币这个场景中它对于数据一致性是有强需求的理论上用单主协议是最优的选择。但是比特币作为去中心化的数字货币是不会使用单主协议的否则又变成中心化的系统了。因此比特币只能选择多主协议通过 POW 协议将比特币整条链操作进行了近似串行化这样才能降低出现双花的概率并发写的时候一个比特币被消费多次鱼与熊掌不可兼得既然要强一致性那么只能牺牲性能来换取。
由于多主协议允许了数据分歧那么就需要有解决数据冲突的策略来保证最终一致性。如果要严格区分的话比特币实际上应用了两个一致性协议
POW决定节点的记账权起到类似单主协议中定序器的作用。注意 POW 也是多主协议尽管概率很低但是它有可能出现多个节点同时算出答案一起出块并发写的情况此时我们称比特币出现了分叉即出现了数据冲突。Gossip用于将出块的交易同步到全球所有节点。由于 POW 会出现并发写的情况当一个节点同时接受到多个节点写入请求时就需要解决数据冲突的问题。比特币解决数据冲突的方式就是当出现分叉时选取最长的那条链作为主链其他分叉的链上的交易会被回滚等待重新打包出块。
总结
本文主要从是否允许数据分歧的角度将分布式一致性协议分为两种单主协议和多主协议。其中单主协议会用一个主节点来负责写操作这样能够保证全局写的顺序一致性但因此也牺牲了一部分性能。而多主协议则允许写操作可以由不同节点发起并且同步给其他副本只能保证最终一致性但因此也提升了系统并发写入的性能。对数据一致性要求高的场景例如分布式数据库主要会使用单主协议对数据一致性要求不高例如故障检测主要会使用多主协议来提高性能当然也有特例像比特币为了去中心化使用 POW 和 Gossip 结合进行数据复制。
值得注意的是文中提到的单主、多主协议只是我个人对分布式一致性协议的一种分类方式帮助我们更好的理解。读者可以看一下参考资料看一下不同作者对分布式协议是如何分类的这样对分布式一致性协议会有更深入的理解。
原文链接 本文为云栖社区原创内容未经允许不得转载。