坚持思考,就会很酷
注意,今天是大白话随便聊聊,目的是直白的了解 raft 是什么,不用太抠理论定义。
什么是一致性协议?
字面理解就是让某些东西保持一致的协议嘛。
什么是一致?
大白话就是内容完全相同呗。以存储场景举例,假设有三个磁盘文件,大小为 1M ,如果三个文件 1M 的数据都完全相同,那么这可以说这文件的数据是一致的。
一致性还分了不同的等级,如线性、因果、最终一致性等等,而且如果站在不同的系统层面来看,承诺的一致性也会有所不同。这些今天都不重要,重要的是我们知道了:一致性协议就是用来达到一致的协议呗。
有两个最出名的一致性协议:paxos 和 raft 。数学上已经严格证明了 paxos 的正确性,只要严格遵守它协议的约束,就能保证在分布式的恶劣环境下多副本数据的一致。我们来看一下吧!
paxos 是 Leslie Lamport 大神于 1990 年提出的一致性协议。它解决的问题是一个分布式系统如何就某个值(决议)达成一致。
划重点:paxos 协议本质是确定一个值。
论文《The part-time parliarment》提到的 paxos 里面有两个重要角色:
它们的操作对象就是:提议( Proposal ) = 提议的值 + 提议编号。里面有三大"定律",满足这三大约束条件,那么就能保证一致性:
第一定律:每轮的投票编号唯一;
第二定律:投票满足多数才算成功(并且如果任意两次投票都存在多数派,则多数派的交集不为空);
第三定律:如果一轮编号为 Bbal 的投票,多数派中任意一位成员曾投过 Bbal 编号小的票(B'),那么 Bdec == B'dec;
上面就是 paxos 最核心的内容,但是说实话,每一个字都看得懂,但是连起来就不知道啥意思?
paxos 到底能做啥?这个我们存储系统有啥关系?它为啥那么难懂?
paxos 难就难在于它没告诉大家,这个东西能用来做啥,映射不到现实,就无法产生共鸣。
我们先接受一个事实:paxos 的本质是确定一个值,且一旦这个值确定之后,后续无论怎么投票,无论发生什么,这个值保持不变。
那我就比以前更懵逼了!怎么越说越糊涂了了,说好的做一个分布式存储服务吗?存储服务应该允许可以写入任何数据,且可以 Update 的嘛。
确定一个不能变的值有啥用?
我们下面尝试将 paxos 工程化,将它具现化到现实的工程实现。
1 确定一个值,有啥用?
回到最开始的问题,确定一个值对我们有啥用?
我们来简要发散下 paxos 工程化的思路。
paxos 本质:确定一个值,现在把这里面参与的角色打包起来,Proposer,Acceptor,Proposal 等等组成的抽象的集合:paxos instance,称为 paxos 实例:
划重点:每个实例必须是完全独立,投票互不干涉,即可。
一个 instance 确定一个值,多个 instance 确定多个值。
这些值不断的被确定(永不更改),形成了一个值序列,这有啥用?
2 确定多个值有啥用?
接着上面,我们现在有了一系列永远无法被修改了值序列,有啥用?存储服务的基本特点是允许存储任何数据,并且能够增删改。
哪还有啥用?
这一个个值序列像不像一个东西:日志!
这个跟 rocksdbdb,leveldb 的 wal 日志是不是差不多意思了?
我们应用这些日志就能得到一致性的输出。所以我们还缺个啥?
状态机嘛。
3 加个状态机就起飞了
什么是状态机?
状态机全称为有限状态机。它接收条件的触发,由一种状态转变为新的状态。初始状态相同,输入的一系列事件相同,那么它最终的状态一定相同。
这可太常见了,比如 rocksdb,leveldb 等等 lsm 存储,它们数据先写 append log ,通过重放日志到达的系统状态一定是一致的。
这种状态机的应用模式可不仅限于存储服务。
到这,我相信童鞋们已经很豁然开朗了,只要我们通过 paxos 来产生分布式一致的有序的操作日志,加上状态机的配合,实现一个分布式存储服务必然不是问题。
通过不停的确定一个个值,形成一个有序的操作系列,配合状态机的应用,这,就是 paxos 的工程化方向。
4 活锁的问题怎么解决?
对于 paxos 来说,Proposer 和 Acceptor 角色是可以重叠的,每个节点既可以是 Proposer,也可以是 Acceptor ,或者两者都是。
这带来了非常大的灵活,每一个 Proposer 都可以递交协议(写入数据),但由于最终只能确定一个值,那么这会导致非常多的无效功,这期间是使用类似乐观锁来解决那些冲突的提议。
比如说,A 刚递交一个提案,B 就递交一个新提案导致 A 的提案被否定了,然后 A 又迅速递交一个提案,形成了一种类似活锁的状态,这时间就浪费了呀。
怎么解决?
问题根因在于可以提案的点太多,大家都是平等的。那么统一声音才能解决这个问题。于是Leader 就应运而生。通过某种方法指定一个节点为 Leader ,只有一个节点能递交提案,这样就解决了混乱问题,效率提随之提升(这就是 Multi-Paxos )。
5 paxos 工程化小结
小结一下,如果要将一个 paxos 工程化落地,衍生了哪些东西:
慢着,这个工程化方向咋这么眼熟呢?
这不就是 raft !
终于到了 raft 协议,raft 的论文开篇就是这么一段话:
Raft is a consensus algorithm for managing a replicated log. It produces a result equivalent to (multi-)Paxos, and it is as efficient as Paxos, but its structure is different from Paxos;
raft 证明和 paxos 等价,raft 是一种日志复制的一致性算法。
看懂了吗?raft 的着眼点就是 日志+状态机 的方向。
划重点:raft 天生就是 paxos 协议工程化的一种样子。
如下图:
图里交代了关键模块:
raft 确实比 paxos 简单啊,因为它已经把实现程序交互的样子都画出来了。
在 raft 论文里面直接把几个因素交代清楚了:
说实话,上面的这些知识点都是我们对 paxos 工程化的长时间推导才想明白的。
没想到 raft 论文上来就给整好了,所以我才说,raft 协议出生就是为了解决工程化的问题的。
raft 把一致性归纳成三个核心问题:
其实真正要做的就两个,第三个问题贯穿前两个事情:
我们下面来看下这两个事情是怎么做的。
而用户则只好奇两个事情:
1 Leader 选举
角色转变:
简单看下 raft 协议中关于 Leader 选举的部分。下面是角色转化图,非常清晰:
图里至少能得到这么几点知识点:
Leader 选举成功之后则可以对外提供服务。
在论文中,为了让选举更高效(避免类似活锁的场景),各个节点的定时器间隔是随机值。
服务时间线:
从时间线来看,可以分为两部分时间(如下图):
每个 Leader 都有自己的任期,注意:无 Leader 的状态是停服状态。
Leader 选举的规则?
被多数节点接受并且持久化的的日志叫做 committed log 。
说实话,Leader 选举的规则其实就一条:具备完备的 committed 的 log 数据即可。
那怎么才能选出具有完备数据的节点呢?
这就是 raft 协议里安全性的内容。投票发起者( Candidate )要告诉对方两个东西:
其他节点( Follower )收到这两个信息会决定要投它一票,还是拒绝它?
划重点:做这个决定依赖于它的日志是不是比我新(全)。
那怎么判断谁更新(全)呢?
1 . 先比 term ,谁更大谁就新;
2 . 如果任期相同,那么就比较 index ,index 谁更大就新;
我们看一眼下图,我们知道 raft 的操作对象就是日志。在 raft 协议中,每个日志都有唯一的编号:index ,代表了它唯一的槽位。
题外话:这里可以类比上面 paxos 章节说的 instance 概念。其实每一个日志槽位和其他模块对象结合其他就是单独的 instance ,这一系列的日志对象就类似于 paxos 多实例 instance 确定的值。
每个 index 槽位代表的值一旦确定将永不更改,它们的确认不相互影响。
从完备的数据来看 committed 的位置在 index:7 这个位置。那么第一个节点、第三个节点、第五个节点都具备完备的数据,但是按照协议跑起来,只有第一个节点和第三个节点才有可能会成为 Leader 。因为它们两个节点有最新的数据(虽然是没有 commited 的),第五个节点找它们投票的时候,会被拒绝(它虽然有完备的数据,但是不够新)。
2 日志复制
日志复制有几个特点:
和 paxos 类似,每个日志槽位的值一旦确定就无法更改,无论怎么投票,怎么运转,这个值不再变更。raft 就这样连续的确定值就能形成一个的日志序列,给到状态机使用。
这里类比 paxos 的 instance ,其实我们只需要保证每个槽位的投票和数据的独立就和 instance 的是一个效果。
以这个图为例,在不切主的情况下,数据从节点(1)向其他节点发送,补齐数据。
经过状态机应用,所有的节点最终系统状态一致:
思考一个问题:如果用户写失败了,系统提供了什么结果语义?
划重点:未定义。有可能写入了,有可能没写入。这种场景只能依赖于用户重试。标准的存储服务写失败语义。
还是以上图举例,就拿 index:8 这个位置的写入来说,用户从节点(1)写入数据 x=4。
场景一:这个时候只把日志成功复制到节点(3)就挂了。用户那边自然是失败的。节点(1)恢复后,还是又成为了 Leader ,由于 leader 永远不会删改日志,所以最终还是会把 index 的日志复制到其他节点,等复制完之后,满足 quroum 系统状态就变了就变成 x=4 了。
场景二:一条日志没写入,那么系统状态就还是 x=5 ;
所以,用户写入失败的场景,一定要依赖重试。不能对结果假定。这种假定在存储系统中通用。
关于 raft 日志复制,有个规则不得不提:Leader 永远不能 commit 非自己任期的日志。哪怕已经满足 quorum 。
为什么会有这个限定 ?
看一个 raft 论文中的简单的例子:
这是一个时间序列,从 a -> b -> c -> d -> e :
看到了吗?
为什么在 c 时刻一直强调,不要认为 index:2 满足了 quorum 就认为是 committed 的日志,然后就去 apply 。因为你一旦这样做了,d 时刻的场景发生之后,index:2 的日志是被修改了。
这就导致 index:2 两次 commit 了不同的 log !这就违背了一个槽位确定一个值,永不更改的承诺。
这绝对不行。
怎么办?
解决很简单,上面已经讲了,在 c 时刻这种场景,就算 index:2 被复制到多数,满足了 quorum 也不能认为是 committed ( 没有 commit 自然就不能 apply ),Leader 只能 commit 自己任期的日志。前面的日志将被间接的递交。
再谈谈 e 时刻为什么把 index:3 的日志复制到多数之后,就可以认为 index:2 被 commit 了?
因为,这样做了之后,将不可能出现 d 时刻的场景。因为 S5 的任期只有 3 !它将不可能成为 Leader 。
题外话:etcd 在每次选举出 Leader 的第一件事就是广播一条空白消息,原因就在这里。目的是为了间接 commit 掉前任的日志。
3 状态机
这部分其实是最简单的,状态机做的事情我们叫做 apply 。apply 的内容则是各个业务自行解释,举个例子,如下的日志,这是一个典型的 kv 系统的样子:
日志 apply 完之后,系统状态为:
x = 4
y = 7
划重点:日志里面的内容由业务自行解释,raft 只保证日志复制是完全一致的。
4 Propose 递交
用户的入口就是从递交 Propose 开始,由 Leader 接收用户请求,然后封装成日志的样子,经过了 commit( 确定这个值 )之后就能对外承诺。
思考一个小问题:集群只有一个 Leader ,如果请求发给了 Follower 呢?难不成 Client 还要专门记录谁是 Leader ?
也没关系,Follower 可以透明转发给 Leader 。Leader 处理好之后,回应即可。
划重点:还是那句话,只由 Leader 来发起,就算发给了 Follower ,请求也会转发 Leader。
5 成员变更
成员变更一般分为两种场景:
场景一:单节点变更
这是绝对安全的,因为它不会直接影响 Leader 的地位。这种的处理也简单。把集群变更的消息作为一条日志广播到集群,被集群 commit 之后,就可以直接 apply 新配置了。
划重点:集群变更也可以作为日志消息。 还是那句话,日志里面的内容可以是任何东西,业务自行解释。raft 只保证它的一致即可。
举个栗子:
原始集群 (S1,S2,S3),现在扩容一台 S4 ,只需要封装一条 < add S4 > 这样的日志消息,广播到集群里就可以,等这条消息 commit 了,就可以变更配置了。
场景二:多节点变更
多节点的配置则不能这样做,为什么?
因为怕一次性来的人太多,直接威胁到原有 Leader 的权威。如下:
比如说,原有集群 ( S1,S3,S3 ),一次性来了两个 ( S4,S5 ),这就可能导致某个时刻出现两个 Leader 的情况:
那这可不行,这不就脑裂了嘛。一个集群只能有一个 Leader ,不然就会出现数据混乱的情况。
那怎么解决这个问题呢?
通用的做法是 joint consensus 算法。其实这个算法很简单,就是加一个中间过程,集群配置搞成两阶段切换,过程中要满足新集群和老集群的同时的 quorum 投票。
这个图怎么看不懂?我举个栗子:
最开始集群配置( S1,S2,S3 ),我们暂且叫做 C_old ;
递交两条集群变更的日志,Add S4,Add S5 ,Leader 向所有 S1,S2,S3 广播日志;
所有节点( S1,S2,S3 )收到这两条日志,则代表这两条日志被 commit 了,于是 apply 这两条日志,apply 的行为:集群配置变更为( S1,S2,S3,S4,S5 )&( S1,S2,S3 ),俗称 C_old,new ;
在 etcd 中,对应 enter joint 的操作;
开始递交一个切换配置的日志消息( etcd 里面叫做 ConfChangeV2 ),并且广播这条配置;
所有节点( S1,S2,S3,S4,S5 )收到这条日志则代表这条日志被 commit,于是可以 apply 这条日志,apply 的行为:集群配置变更为( S1,S2,S3,S4,S5 ),这个配置就是 C_new,至此,配置变更结束;
重点提一下:在 C_old,C_new 阶段如果收到写请求,需要满足两份配置的 quorum 同意才能 commit 。
这样就解决了双 Leader 的问题。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/C8Mgl9ebMAG0hh6ekoO58w
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。