分布式系统的一致性与共识算法(三)

顺序一致性(Sequential Consistency)

ZooKeeper

一种说法是ZooKeeper是最终一致性,因为由于多副本、以及保证大多数成功的ZAB协议,当一个客户端进程写入一个新值,另外一个客户端进程不能保证马上就能读到这个值,但是能保证最终能读取到这个值。另外一种说法是ZooKeeper的ZAB协议类似于Paxos,提供了强一致性。但这两种说法都不准确,ZooKeeper文档中明确写明它的一致性是Sequential Consitency即顺序一致。ZooKeeper中针对同一个FollowerA提交的写请求request1、request2,某些Follower虽然可能不能在提交成功后立即看到(也就是强一致性),但经过自身与Leader之间的同步后,这些Follower在看到这连个请求时,一定是先看到request1,request2,两个请求之间不会乱序,即顺序一致性。
其实,实现ZooKeeper的一致性更复杂一些,ZooKeeper的读操作是sequential consistency的,ZooKeeper的写操作是linearizability的,关于这个说法,ZooKeeper的官方文档中没有写出来,但是在社区的邮件组有详细的讨论。ZooKeeper的论文《Modular Composition of Coordination Services》中也有提到这个观点。

总结一下,可以这么理解ZooKeeper:从整体(read操作 + write操作)上来说是sequential consistency,写操作实现了Linearizability

线性一致性(Linearizability)

线性一致性又被称为强一致性、严格一致性、原子一致性。是程序能实现的最高的一致性模型,也是分布式系统用户最期望的一致性。CAP中的C一般就指它。顺序一致性中进程只关心大家认同的顺序一样就行,不需要与全局时钟一致,线性就更严格,从这种偏序(partial order)要达到全序(total order)要求是:

  • 1.任何一次读都能读到某个数据的最近一次写的数据
  • 2.系统中的所有进程,看到的操作顺序,都与全局时钟下的顺序一致。

以前面讲的例3继续讨论:

B1看到X的新值,C1反而看到的是旧值,即对用户来说,x的值发生了回跳

在线性一致的系统中,如果B1看到的x值为1,则C1看到的值也一定为1。任何操作在该系统生效的时刻都对应时间轴上的一个点。如果我们把这些时刻连接起来,如图中紫线所示,则这条线会一致沿时间轴向前,不会反向回跳。所以任何操作都需要互相比较决定,谁发生在前,谁发生在后。例如B1发生在A0之前,C1发生在A0之后,而在前面顺序一致性模型中,我们无法比较诸如B1和A0的先后关系。线性一致性的理论在软件上有哪些体现呢?
在这里插入图片描述

etcd与raft

上面提到ZooKeeper的写是线性一致性,读是顺序一致性。而etecd读写都做了线性一致,即etcd是标准的强一致性保证。
etcd是基于raft来实现的,raft是共识算法,虽然共识和一致性的关系很微妙,经常一起讨论,但共识算法只是提供基础,要实现线性一致还需要在算法之上做出更多的努力如库封装,代码实现等。如Raft中对于一致性读给出了两种方案,来保证处理这次读请求的一定是Leader:

  • 1.ReadIndex
  • 2.LeaseRead
    基于Raft的软件有很多,如etcd、tidb、SOFAJRaft等,这些软件在实现一致读时都是基于这两种方式。这里对ReadIndex和Lease Read做下解释,即etcd中线性一致性读的具体实现。由于在Raft算法中,写操作成功仅仅意味着日志达成了一致(已经落盘),而并不能确保当前状态机也已经apply了日志。状态机apply日志的行为在大多数Raft算法的实现中都是异步的,所以此时读取状态机并不能准确反映数据的状态,很可能会读到过期数据。
    基于以上这个原因,要想实现线性一致性读,一个交为简单通用的策略就是:每次读操作的时候记录此时集群的committed index,当状态机的apply index大于或等于committed index时才读取数据并返回。由于此时状态机已经把度请求发起时的已提交日志进行了apply动作,所以此时状态机的状态就可以响应度请求发起时的状态,符合线性一致性读的要求。这便是ReadIndex算法。
    那如何准确获取集群的committed index?如果获取到的committed index不准确,那么以不准确的committed index为基准的ReadIndex算法讲可能拿到过期数据。为了确保committed index的准确,我们需要:
  • 1.让leader来处理读请求
  • 2.如果follower收到读请求,将请求forward给leader
  • 3.确保当前leader仍然是leader
    leader会发起一次广播请求,如果还能收到大多数节点的应答,则说明此时leader还是leader.这点非常关键,如果没有这个环节,leader有可能因网络分区等原因已不再是leader,度请求依然由过期的leader处理,那么久将有可能读到过去的数。这样,我们从leader获取的committed index久作为此次读请求的ReadIndex.

以网络分区为例:

在这里插入图片描述

  • 1.初始状态时集群有5个节点:A、B、C、D和E,其中A是leader;
  • 2.发生网络隔离,集群被分割成两部分,一个A和B,另外一个是C、D、E。虽然A会持续向其他介个节点发送headerbeat,但由于网络隔离,C、D、E将无法接收到A的heartbeat。默认地,A不处理向follower节点发送heartbeat失败(此处为网络超时)的情况(协议没有明确说明heartbeat是一个必须收到follower ack的双向过程);
  • 3.C、D、E组成的分区在经过一定时间没有收到leader的heartbeat后,触发election timeout,此时C成为leader.此时,原来5节点集群因网络分区分割成两个集群:小集群A和B;大集群C、D、E,C为leader
  • 4.此时客户端进行读写操作。在Raft算法中,客户端无法感知集群的leader变化(更无法感知服务端有网络隔离的事件发生)。客户端在向集群发起读写请求时。如果客户端一开始选择C节点,并成功写入数据(C节点集群已经commit操作日志),然后因客户端某些原因(比如断线重连),选择节点A进行读操作。由于A并不知道另外3个节点已经组成当前集群的大多数并写入了新的数据,所以节点A无法返回准确的数据。此时客户端将读到过期数据。不过相应地,如果此时客户端向节点A发起写操作,那么写操作将失败,因为A因网络隔离无法收到大多数节点的写入响应
  • 5.针对上述情况,其实节点C、D、E组成的新集群才是当前5节点集群中大多数,读写操作应该发生在这个集群中而不是原来的小集群(节点A和B).如果此时节点A能感知它已经不再是集群的leader,那么节点A将不再处理读写请求。于是,我们可以在leader处理读写请求时,发起一次check quorum环节:
    leader向集群的所有节点发起广播。当leader还能收到集群大多数节点的响应,说明leader还是当前集群的有效leader,拥有当前集群完整的数据,否则,读请求失败,将迫使客户端崇训选择新节点进行读写

这样一来,Raft算法久可以保障CAP中的C和P,但无法保障A:网络分区时并不是所有节点都可以响应请求,少数节点的分区将无法进行服务,从而不符合Availablility。因此,Raft算法是CP类型的一致性算法

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

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

相关文章

【车载开发系列】SID$11服务配置

【车载开发系列】SID$11服务配置 前言 ECUReset(ECU重置),ECU作为Server端,执行Client发送来ECU Reset请求中重启的类型(通过子服务区分)。对于UDS协议关于处理该请求的逻辑,没有强制性定义。 Step1:SID和SubFunction的追加 BasicEditor→Dcm→DcmConfigSet→DcmDs…

vs2019 c++里用 typeid() . name () 与 typeid() . raw_name () 测试数据类型的区别

(1) 都知道,在 vs2019 里用 typeid 打印的类型不大准,会主动去掉一些修饰符, const 和引用 修饰符会被去掉。但也可以给咱们验证学到的代码知识提供一些参考。那么今天发现其还有 raw_name 成员函数,这个函…

AES分组密码

一、AES明文和密钥位数 RIJNDAEL 算法数据块长度和密钥长度都可独立地选定为大于等于 128 位且小于等于 256 位的 32 位的任意倍数。 而美国颁布 AES 时却规定数据块的长度为 128 位、密钥的长度可分别选择为 128 位, 192 位或 256 位 1.1 状态 中间结果叫做状态…

建模:3dmax

3Dmax 制作模型和动画(橘肉); RizomUV 对模型进行展UV(橘皮); Substance Painter 纹理手绘(给橘皮制定想要的皮肤); 1.基础 1.1可编辑多边形、可编辑样条线 体、面都需要…

Polylang Pro插件下载:多语言网站构建的终极解决方案

在全球化的今天,多语言网站已成为企业拓展国际市场的重要工具。然而,创建和管理一个多语言网站并非易事。幸运的是,Polylang Pro插件的出现,为WordPress用户提供了一个强大的多语言解决方案。本文将深入探讨Polylang Pro插件的功能…

暴力数据结构之二叉树(堆的相关知识)

1. 堆的基本了解 堆(heap)是计算机科学中一种特殊的数据结构,通常被视为一个完全二叉树,并且可以用数组来存储。堆的主要应用是在一组变化频繁(增删查改的频率较高)的数据集中查找最值。堆分为大根堆和小根…

什么是最大路径?什么是极大路径?

最近学习中,在这两个概念上出现了混淆,导致了一些误解,在此厘清。 最大路径 在一个简单图G中,u、v之间的距离 d ( u , v ) min ⁡ { u 到 v 的最短路的长度 } d(u,v) \min \{ u到v的最短路的长度 \} d(u,v)min{u到v的最短路的…

wefaf

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…

每天Get一个小技巧:用DolphinScheduler实现隔几天调度

转载自tuoluzhe8521 这篇小短文将教会你如何使用Apache DolphinScheduler实现隔几天调度,有此需求的小伙伴学起来! 1 场景分析 DolphinScheduler定时器模块-定时调度时每3秒|每3分钟|每3天这种定时,不能够跨分钟,跨小时&#x…

【C++】:string类的基本使用

目录 引言一,string类对象的常见构造二,string类对象的容量操作三,string类对象的访问及遍历操作四,string类对象的修改操作五,string类非成员函数六,整形与字符串的转换 引言 string 就是我们常说的"…

如何对SQL Server中的敏感数据进行加密解密?

为什么需要对敏感数据进行加密? 近几年有不少关于个人数据泄露的新闻(个人数据通常包含如姓名、地址、身份证号码、财务信息等),给事发公司和被泄露人都带来了不小的影响。 许多国家和地区都出台了个人数据保护的法律法规&#…

Unity Animation--动画窗口指南(使用动画视图)

Unity Animation--动画窗口指南(使用动画视图) 使用动画视图 window -> Animation 即可打开窗口 查看GameObject上的动画 window -> Animation -> Animation 默认快捷键 Ctrl 6 动画属性列表 在下面的图像中,“动画”视图&am…

思科模拟器--2.静态路由和默认路由配置24.5.15

首先,创建三个路由器和两个个人电脑。 接着,配置两台电脑的IP,子网掩码和默认网关 对Router 0,进行以下命令: 对Router进行以下命令: 对Router2进行以下命令: 本实验完成。 验证:PC…

Vue3+ts(day06:路由)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学,可以点心心支持一下哈(笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】,记录一下学习笔记,用于自己复盘,有需要学…

【ARMv8/v9 系统寄存器 5 -- ARMv8 Cache 控制寄存器 SCTRL_EL1 使用详细介绍】

关于ARM Cache 详细学习推荐专栏: 【ARM Cache 专栏】 【ARM ACE Bus 与 Cache 专栏】 文章目录 ARMv8/v9 Cache 设置寄存器ARMv8 指令 Cache 使能函数测试代码 ARMv8/v9 Cache 设置寄存器 关于寄存器SCTRL_EL1 的详细介绍见文章:【ARMv8/v9 异常模型入…

西南大学计算机考研,选学硕还是专硕?西南大学计算机考研考情分析!

西南大学(Southwest University)是教育部直属,教育部、农业农村部、重庆市共建的重点综合大学,是国家首批"双一流"建设高校,"211工程"和"985工程优势学科创新平台"建设高校。现任党委书…

【嵌入式大赛应用赛道】机械手臂

电机 进步电机:它的转动是以确定的步数进行的,只要计算好脉冲数量和频率,就可以准确预测和控制电机的转动角度、速度以及停止的位置 伺服电机:将输入的电信号(如电压或电流指令)转换成轴上的精确旋转运动…

大模型算法(一):从Transformer到ViT再到LLaMA

单任务/单领域模型 深度学习最早的研究集中在针对单个领域或者单个任务设计相应的模型。 对于CV计算机视觉领域,最常用的模型是CNN卷积模型。其中针对计算机视觉中的不同具体任务例如分类任务,目标检测任务,图像分割任务,以CNN作…

【传知代码】VRT: 关于视频修复的模型(论文复现)

前言:随着数字媒体技术的普及,制作和传播视频内容变得日益普遍。但是,视频中由于多种因素,例如传输、存储和录制设备等,经常出现质量上的问题,如图像模糊、噪声干扰和低清晰度等。这类问题对用户的体验和观…

几个排序器的verilog及其资源占用、延时分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 因为课题需要,调研了几个快速排序方法,并手写或者改进了若干待测试对象,包括记分板型冒泡排序(这个是别人的&#xff09…