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

顺序一致性(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.hqwc.cn/news/705264.html

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

相关文章

mysql的explain

explain可以用于select,delete,insert,update的statement。 当explain用于statement时,mysql将会给出其优化器(optimizer)的执行计划。 通过explain字段生成执行计划表。下面来解析这个执行计划表的每一列…

【以规划为导向的自动驾驶】Planning-oriented Autonomous Driving

ABSTRACT 研究背景: 现代自动驾驶系统是顺序化地排列多个任务模块, 近期的主流方法: ①为单个任务部署独立模型 ②设计具有分离式头部的多任务(multi-task)范式。 但是,这些方法会累积误差或任务间协同不足而不利于自动驾驶。 作者认为重…

战网国际服注册教程 暴雪战网国际服账号注册一站式教程分享

战网国际版,也即Battle.net环球版,是由暴雪娱乐操刀的全球化游戏交流枢纽,它突破地理限制,拥抱全世界的游戏玩家。与仅限特定地区的版本不同,国际版为玩家开辟了无障碍通道,让他们得以自由探索暴雪庞大游戏…

免费体验GPT-4o这5大功能,非常好用!

这几天,OpenAI发布了新的GPT版本,GPT-4o,比GPT4更加智能也更快。 据说,GPT-4o在文本、推理和编码智能方面实现了GPT-4 Turbo级别的性能,在多语言、文本、音频和视觉功能方面甚至超过了市面上所有同类产品。 有几个亮点…

潮玩与游戏的结合点——潮玩宇宙App与链游

本文主要介绍了潮玩宇宙App的开发过程及其链游的开发,探讨了潮玩与游戏的结合点,分析了其市场前景和潜在风险,并提出了相应的建议。 一、潮玩宇宙App的开发背景 随着互联网的普及和人们对娱乐方式的多样化需求,潮玩市场逐渐崛起…

结合小波变换的遥感语义分割网络,融合频域和空间域特征提升分割效果

题目:SFFNet: A Wavelet-Based Spatial and Frequency Domain Fusion Network for Remote Sensing Segmentation 论文:http://arxiv.org/abs/2405.01992 代码:https://github.com/yysdck/SFFNet 年份:2024 创新点 两阶段网络SFFNet:网络首先使用空间方法提取特征,以保…

Java开发大厂面试第03讲:线程的状态有哪些?它是如何工作的?

线程(Thread)是并发编程的基础,也是程序执行的最小单元,它依托进程而存在。一个进程中可以包含多个线程,多线程可以共享一块内存空间和一组系统资源,因此线程之间的切换更加节省资源、更加轻量化&#xff0…

IEEE(电气电子工程师学会)数据库文献去哪里查询下载

IEEE数据库简介: IEEE(电气电子工程师学会)是目前全球科学技术领域领先的专业机构。其期刊在电气电子工程、计算机科学、人工智能、机器人、自动化控制、遥感和核工程领域的期刊影响因子和被引用量都名列前茅。而其学术会议涉及领域广&#…

哈夫曼编码的应用

数据结构与算法课的一个简单实验,记录一下,以供参考。 文章目录 要求测试样例统计字母出现次数建立哈夫曼树对字符编码对原文进行编码译码 要求 输入一段100—200字的英文短文,存入一文件a中。统计短文出现的字母个数n及每个字母的出现次数…

【LAMMPS学习】八、基础知识(6.6)在 Windows 10 上使用 LAMMPS 和 WSL

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

[董晓算法]搜索相关题目及模板

前言: 本系列是学习了董晓老师所讲的知识点做的笔记 董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com) 动态规划系列(还没学完) 【董晓算法】动态规划之线性DP问题-CSDN博客 【董晓算法】动态规划之背包DP问题&#xff…

x264 帧类型代价计算原理:slicetype_mb_cost 函数分析

slicetype_mb_cost 函数 函数功能 计算每个宏块 MB 的代价 cost。函数参数分析 x264_t *h:全局编码结构体x264_mb_analysis_t *a:宏块分析结构体x264_frame_t **frames:系列帧数据结构体int p0:帧序号之一,一般指向靠前帧int p1:帧序号之一,一般指向靠后帧int b:帧标志…