海量存储之十八--一致性和高可用专题

简介: 我们已经在上面的分析中,我们已经看到observer模型在多机场景下的问题,所以,paxos模型的目标就是解决这个问题,他解决这个问题的方法就是quorum模型。 我的目标是让大家能弄明白,掌握这些复杂的概念,所以我也会将以前我在淘宝java中间件团队内分享时候,大家经常犯的一些错误,也写到【】里

我们已经在上面的分析中,我们已经看到observer模型在多机场景下的问题,所以,paxos模型的目标就是解决这个问题,他解决这个问题的方法就是quorum模型。

我的目标是让大家能弄明白,掌握这些复杂的概念,所以我也会将以前我在淘宝java中间件团队内分享时候,大家经常犯的一些错误,也写到【】里面,尽可能让大家少走弯路,如果有什么感想,疑问,后面可以留言。

 

PS 广告插播 : 淘宝java中间件团队,你值得拥有:)

 

----PAXOS------

好,我们回顾一下上下文,我们在上篇文章中谈到,当机器变得更多的时候Observer不能只有一个。必须有更多个Observer,但Observer多了,到底听谁的又成了问题。你一言我一语,大家都觉得自己是老大,谁也不服谁。咋办捏?

这时候就得有人站出来,说:那我们少数服从多数吧!制定一套策略,在各种情况下都能够选出一个决议不就行了!

这其实就是paxos协议的核心想法之一,我们来看一下他是怎么做到的。在这里,我不想去做那个繁琐的证明过程,那个过程如果你感兴趣,可以去看paxos made simple这篇文章,有中文,这里给出http://blog.csdn.net/sparkliang/article/details/5740882 ,数星星同学也翻译过。可以直接google.

 

我在这里只说结论,因为结论更容易理解一些。

我们假定有A,B,C,D,E五台机器。kv系统需要put一个数据[key=Whisper -> val=3306]到我们这5台机器上,要保证只要反馈为真,任意两台机器挂掉都不会丢失数据,并且可以保证高可用。怎么做:

1.首先,客户端随机选择一个节点,进行写入提交,这里我们随机选择了C这个节点,这时候C节点就是这次提议的发起人【也叫proposer,在老的2pc协议里也叫做coodinator】,当C收到这个提议的时候,C首先要做的事情是根据当前节点的最新全局global id,做一次自增操作,我们假定,在当时全局id,Global ID是0,所以,这个议案就被对应了一个编号,1--->[key=Whisper -> val=3306]。

【【这里有两个我们经常犯的错误,下面做一个解说:

1.global id问题,在老的论文里,Lamport没有描述这个自增id是怎么生成的,所以大家的第一个疑问一般是问id怎么生成,从我目前能够看到的所有实现里面,基本上就是选择哪一台机器,就是以那台机器当前所保持的全局id(snapshot,可能不是全局来看的最高值,但没关系,只要是自己这台机器的最高值就行了),然后做一下自增就行了。我们后面会看到协议如何保证非全局最高值的globalID提议会被拒绝以至于不能够形成决议。

2.global id --->[key=Whisper -> val=3306] . 这也是个会让人困惑的问题,在原文中,他被表示为一个key-value的形式,比如proposal[0->value] 。这会让人自然的联想到与数据库的kv相对应,key是0,value是value。然后就会困惑,这个数据是怎么和数据库对应起来的呢?这是我当时的困惑,现在也把他列在这里。其实很简单,这里的global id对应value.global id只是对paxos协议有意义,对于数据库,其实只需要关心value里面的数据即可,也即将global id --->[key=Whisper -> val=3306]里面的value: [key=Whisper-> val=3306] 作为数据库构建映射时所需要的redoLog就行了,global id的作用只是告诉你这些数据的顺序是按照global id来排列的,其他无意义。    】】

 

我们回到文中,我们已经将这个新的议案标记了从C这台机器看起来最大的global id : 1--->[key=Whisper -> val=3306]。然后,他会尝试将这个信息发送给其余的A,B,D,E这几台机器。

我们来看这些机器的操作流程。 在这个过程中,Paxos将A,B,D,E叫做accepter【老的协议里没有区分,管这些都叫做参与者,cohorts】,他们的行为模式如下:

如果A,B,D,E这几台机器的globalID 小于C给出的决议的GID(1--->[key=Whisper -> val=3306]),那么就告诉C,这个决议被批准了。而如果A,B,D,E这几台机器的GlobalID 大于或等于C给出决议的GID.那么就告知C 这个决议不能够被批准。

我们假定A,B两台机器当时的Max(GID)是0 ,而D,E的Max(GID)是1.那么,A,B两台机器会反馈给C说协议被接受,这时候我们算算,C的议案有几票了?A+B+!C!,一定要算自己哦:) 。所以,这个议案有三票,5台机器的半数是3.超过法定人数,于是决议就被同意了。

 

 

我们保持这个上下文,来看看D,E这边的情况。首先,要思考的问题是,为什么D,E的Max(GID)是1呢?

其实很简单,D可能在C发起决议的同时,也发起了一个决议,我们假定这个决议是由D发起的,决议是 1--->[key=taobao ->val=1234]。既然D,E的Max(GID)是1,那么意味着E已经告知D,它同意了他的决议,但D马上会发现,A,B,C里面的任意一个都返回了D不同意。他的议案只拿到两票,没有通过,它虽然有点不爽,但也是没办法的事情啊。。

 

这时候C的决议已经被多数派接受,所以他需要告知所有人,我的议案1--->[key=Whisper -> val=3306]已经被接受,你们去学习吧。

 

 

 

这时候还有一个问题是需要被考虑的,如果在C已经得知决议已经达到法定人数,在告知所有人接受之前,C挂了,应该怎么办呢?

我之所以没有将这个放到开始的描述里,主要原因是觉得这是个独立因素,不应该影响议案被接受时候的清晰度。

为了解决这个问题,需要要求所有的accepter在接受某个人提出的议案之后,额外的记录一个信息:当前accepter接受了哪个提议者的议案。

 

为什么要记录这个?很简单,我们看一下上面出现这个情况时候的判断标准。

A 机器:角色-accepter 。 批准的议案 1--->[key=Whisper-> val=3306] 。提议人:C

B 机器:角色-accepter 。 批准的议案 1--->[key=Whisper-> val=3306] 。提议人:C

C机器:角色-proposer 。 挂了。。不知道他的情况。

D 机器:角色-accepter 。 批准的议案 1--->[key=taobao->val=1234] 。提议人:自己

E 机器:角色-proposer。 “提议的”议案 1--->[key=taobao->val=1234] 。提议人:D。

 

因为有了提议人这个记录,所以在超时后很容易可以判断,议案1--->[key=Whisper -> val=3306] 是取得了多数派的议案,因为虽然D,E两台机器也是可以达成一致的议案的。但因为有个人本身是提议者,所以可以算出这个议案是少数派。

就可以知道哪一个议案应该是被接受的了。

 

 

 

在这之后,提议者还需要做一件事,就是告知D,E,被决定的决议已经是什么了。即可。

这个过程在文章中叫Learn. D,E被称为Learner.

别看写的简单,这个过程也是变数最大的过程,有不少方法可以减少网络传输的量,不过不在这里讨论了。

 

 

 

 

下面,我们讨论一下我们在2pc/3pc中面临的问题,在paxos里面是怎么被解决的。

2pc最主要的问题是脑裂,死等。两个问题。

对于脑裂,paxos给出的解决方案是,少数服从多数,决议发给所有人,尽一切努力送达,总有一个决议会得到多数派肯定,所以,不在纠结于某一台机器的反馈,网络无响应?没有就没有吧,其他人有反馈就行了。

所以,如果出现了机房隔离的情况,比如A,B,C在机房1,D,E在机房2,机房1和机房2物理隔离了,那么你会发现,D,E永远也不可能提出能够得到多数派同意的提案。

所以,少数派的利益被牺牲了。。换来了多数派的可用性。我们分析过,这是唯一能够既保证数据的一致性,又尽可能提高可用性的唯一方法。

而对于死等问题,解决的方法也是一样的,对于某一台机器的无响应,完全不用去管,其他机器有相应就行了,只要能拿到多数,就不怕一小撮别有用心的反对派的反攻倒算~。

 

 

 

---------------------------------paxos就是这样一个协议----------

休息一下

----------------------------------------------------------------------------------------

 

 

 

 

那么Paxos有没有什么值得改进的地方?有的,很简单,你会发现,如果在一个决议提议的过程中,其他决议会被否决,否决本身意味着更多的网络io,意味着更多的冲突,这些冲突都是需要额外的开销的,代价很大很大。

为了解决类似的问题,所以才会有zoo keeper对paxos协议的改进。zk的协议叫zab协议,你可以说zab协议不是paxos,但又可以说是paxos.但将paxos和zab协议之间做直接的等同关系,无疑是【错误】的。

 

其实,这也是在我们的现实生活中经常能够发现的,如果每个议案都要经过议会的讨论和表决,那么这个国家的决策无疑是低效的,怎么解决这个问题呢?弄个总统就行了。zab协议就是本着这个思路来改进paxos协议的。

 

 

---------paxos 改进----zab协议讨论-----------------

zab协议把整个过程分为两个部分,第一个部分叫选总统,第二个部分叫进行决议。

选总统的过程比较特殊,这种模式,相对的给人感觉思路来源于lamport的面包房算法,这个我们后面讲。,选择的主要依据是:

1.如果有gid最大的机器,那么他是主机。

2.如果好几台主机的gid相同,那么按照序号选择最小的那个。

所以,在开始的时候,给A,B,C,D,E进行编号,0,1,2,3,4。 第一轮的时候,因为大家的Max(gid)都是0,所以自然而然按照第二个规则,选择A作为主机。

然后,所有人都知道A是主机以后,无论谁收到的请求,都直接转发给A,由A机器去做后续的分发,这个分发的过程,我们叫进行决议。

进行决议的规则就简单很多了,对其他机器进行3pc 提交,但与3pc不同的是,因为是群发议案给所有其他机器,所以一个机器无反馈对大局是没有影响的,只有当在一段时间以后,超过半数没有反馈,才是有问题的时候,这时候要做的事情是,重新选择总统。

具体过程是,A会将决议precommit给B,C,D,E。然后等待,当B,C,D,E里面的任意两个返回收到后,就可以进行doCommit().否则进行doAbort().

为什么要任意两个?原因其实也是一样的,为了防止脑裂,原则上只能大于半数,不能少于半数,因为一旦决议成立的投票数少于半数,那么就存在另立中央的可能,两个总统可不是闹着玩的。

定两个,就能够保证,任意“两台”机器挂掉,数据不丢:),能够做到quorum。。

 

然后是我的个人评述,写zab协议的人否认自己的协议是paxos.变种 其实我也是有些认同的。不过,他们是针对一个问题的两种解决方法:

因为他们解决的问题的领域相同

解决网络传输无响应这个问题的方法也一样:也即不在乎一城一池的得失,尽一切努力传递给其他人,然后用少数服从多数的方式,要求网络隔离或自己挂掉的机器,在恢复可用以后,从其他主机那里学习和领会先进经验。

并且也都使用了quorum方式来防止脑裂的情况。

核心思路是类似的,但解决问题的方法完全是两套。 paxos在其他公司的实现里面也对paxos进行了这样,那样的改进。不过核心思路都是这个。

 

我们对paxos协议的讲解,就到这里。

 

也留下一个问题,zab协议,如果我们用在google 全球数据库spanner上,会不会有什么问题呢?请大家思考哈 

 

后记,抱歉,这篇文章一个图都没有。。我已经尽可能用简单的方式来描述paxos和他的变种协议了(当然有一个作为了问题)。如果有哪个地方不明白,也还请在后面留言吧。友情提示这篇文章不适于跳跃性阅读,想要理解,必须从第一行开始读到最后。。。。

 

google的工程师说,所有的一致性协议都是paxos的特例,我表示不置可否吧。。。。下一篇我们要讨论另外一系的实现,gossip模型的实现。我个人感觉:把gossip归类到paxos模型,似乎也不是很合适。gossip协议的两个主要的实现方式,是dynamo和cassandra.我们在下一篇里面进行讨论

相关文章
|
3月前
|
存储 弹性计算 人工智能
阿里云最新优惠券参考:学生、个人、企业免费领取,优惠券使用教程,选购云服务器可省钱
阿里云最新优惠券参考,阿里云针对学生、个人和企业用户发放了不同种类的优惠券,目前,新用户可领取上云礼包(个人360元,企业1728元),学生用户可领取300元无门槛优惠券(部分公共云产品可用),企业同时还可申请出海扶持抵扣金、算力补贴优惠券等。如果你是老用户,阿里云也会不定期通过系统自动发放金额不等的代金券(160元/50元/10元不等)。通过领取或申请这些优惠券,用户能够以更优惠的价格购买阿里云服务器等云产品,本文为大家介绍这些优惠券的具体金额、领取与使用教程等,以供参考。
|
8月前
|
安全 搜索推荐 数据安全/隐私保护
无缝体验设计、一键直达的奥秘
Apptrace 是一款强大的工具,支持传参安装与一键拉起功能,优化用户体验。本文通过四个实战案例展示其应用:1) 电商深度链接营销,实现商品页直达;2) 游戏邀请系统,追踪来源并自动奖励;3) 新闻个性化内容推送,提升打开速度;4) 企业应用无缝登录,保障安全高效。同时总结最佳实践,包括优雅降级、参数加密、统计分析等,助力企业提升用户转化率与体验流畅度。
|
Ubuntu Linux Shell
Linux系统中如何查看磁盘情况
【9月更文挑战第3天】在Linux系统中,有多种方式查看磁盘情况。可通过命令行工具`df`查看文件系统磁盘使用情况,选项`-h`以人类可读格式显示,`-T`显示文件系统类型;`du`命令显示目录或文件磁盘使用情况,`-h`以人类可读格式显示,`-s`仅显示总计;`fdisk -l`列出磁盘和分区信息。此外,图形界面的磁盘管理工具和文件管理器也可用于查看磁盘使用情况。这些方法有助于更好地管理磁盘空间。
1462 4
|
机器学习/深度学习 人工智能 Cloud Native
在AI师傅(AI-Shifu.com)学习通义灵码的旅程
在这个数字化时代,编程技能愈发重要。通过AI师傅平台,我接触并学习了阿里云推出的通义灵码。从初识到深入学习,我系统掌握了云计算基础、云原生技术、数据库管理和大数据与人工智能等方面的知识。通过实践项目,我不仅巩固了理论,还提升了实际操作能力。通义灵码的易用性和强大功能,让我对云计算有了全新认识。感谢AI师傅提供的学习机会,推荐大家参与征文活动,共同分享学习成果。
|
前端开发 JavaScript Java
如何使用JSR 303 进行后台数据校验?
这篇文章详细介绍了如何使用JSR 303进行后端数据校验,包括JSR 303的基本概念、使用原因、常见操作,以及如何通过注解进行数据校验、分组校验和自定义校验注解的方法和实际应用示例。
如何使用JSR 303 进行后台数据校验?
|
人工智能 自然语言处理 测试技术
通义灵码多维度体验分享
一文带你多维度了解通义灵码
872 4
|
JSON 测试技术 API
探索微服务架构下的API设计最佳实践
微服务架构的普及带来了开发灵活、可扩展的系统的新机遇,但同时也对API设计提出了更高的要求。有效的API设计不仅影响系统的可维护性和可扩展性,还直接影响开发效率和用户体验。本文将深入探讨在微服务架构下如何设计高效、可靠的API,重点介绍RESTful API设计原则、版本控制策略、身份认证机制及错误处理最佳实践,并结合实际案例提供具体的实现建议。
|
缓存 前端开发 CDN
静态资源缓存过期时间的设置
【8月更文挑战第18天】静态资源缓存过期时间的设置
527 1
|
机器学习/深度学习 自然语言处理 搜索推荐
云上智能客服机器人:重塑客户服务体验的新篇章
未来,云上智能客服机器人将继续深化深度学习技术的应用,通过跨领域的知识融合和模型训练提升其在复杂场景下的理解和决策能力。同时,机器人将更加注重多模态交互技术的发展以提供更加自然流畅的交互体验。 4.2 情感智能与人性化服务 随着情感智能技术的不断发展,云上智能客服机器人将更加注重情感交互和人性化服务。机器人将能够识别用户的情感状态和需求偏好提供更加贴心和温暖的服务体验。
848 7
|
机器学习/深度学习 安全 TensorFlow
OpenCV的发展历史
【7月更文挑战第27天】OpenCV的发展历史。
576 3

热门文章

最新文章