使用Paxos前的八大问题

Posted NOSQL追随者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Paxos前的八大问题相关的知识,希望对你有一定的参考价值。

相信不少做存储或者数据库的人已经被Paxos轰炸过过一轮,我也不能免俗,最近也尽可能的翻了一些Paxos的文章,看了这些文章后,我个人感觉最好的理解方式是将Paxos要解决的问题具体化,细节化,然后,我想任何一个有着丰富经验的同学都能不依赖Paxos的任何资料很好的回答这些问题,这些答案的形式化综合起来就应该是网络上的各种Paxos解释。我相信问题导向逐步推导的方式比冲上去学习Paxos文章里面的流程有趣一些,同时,没准还可以发现一个更适合自己业务的改进。


问题一:Paxos[2]解决什么问题?

在保证一致性的前提下,提高系统的可用性。系统中破坏可用性的场景包括,机器down机(硬盘等各种硬件损坏类比),机器间网络丢包、高延时。解决这些问题的根本思路是多副本,这样一个机器down其他副本还可以使用。多副本早已被大家广泛使用,之前最主要的思路是主备机制,又叫做primary-second,或者master-slave,核心思路是主承担所有的操作,并定期异步将主上面数据的变化同步到备。在主备系统运行过程中,如果备出问题,服务不受影响;如果主出问题,就切换到备,因为主总是比备多一点数据,所以这个过程中可能丢数据。丢多少数据呢?这取决于主隔多少时间能将最新的信息同步到备,如果主每隔1小时就能保证1小时前的数据完全到备,那么最多丢一个小时。那么,丢数据的量能缩短吗?5分钟?1秒钟?


对于一个繁忙的数据库系统,1秒钟的数据丢失可能也是灾难,那么最小粒度是什么?就是per request,即主上面每一个变化备都能同步感受到,那么主down掉的时候,备能无损的接管服务,这就是mysql 主备强同步的思路。但是,如果每个request都要备参与,就意味着这个系统如果备挂了就不可服务了,这也是线上恐怕很少有人选择MySQL主备强同步的理由,怎么办?多加几个备来降低备不可用对系统的影响。


多加几个备之后,就带了两个问题,

1. 这些主备之间数据一致性怎么解决?Paxos是一种思路,即多数派同意的就是正确的

2. 那如果主挂了呢,这里有两种选择,一种是任何人在任何时候都可以是主,这时候就没有主备之分了,这是basic paxos[2]的思路;另一种思路是,主挂了就让某一个备成为主,系统可以继续服务,这是viewstamped replication[3]、Raft[4]、Zab[5](广义上可以算Paxos)的思路,在multi-paxos[6]里面也提到了使用leader减少prepare message,leader切换条件更灵活,也可以归类为这个序列。

上面两个问题就是Paxos要解决的核心问题,即Safety(数据是一致的)和Liveness(系统总是能继续前进)。


问题二:状态机(Replication State Machine, RSM)和一致性有何关系

状态机有一个很好的特性:任何初始状态一样的状态机,如果执行的命令序列一样,则最终达到的状态也一样。而存在多个参与者的系统的一致性可以理解为,系统多数成员就某一系列决议得到了相同的判断结果,使用状态机来描述就是,如果在某一个时刻系统不再接受外部输入,则系统中存在多个参与者具有完全相同的状态机。上面两点结合在一起,就得到系统参与者保持一致的关键是,起始状态完全一致,执行命令序列完全一致,那么系统的行为就是可以重复的。这跟单机数据库系统可以类比,数据库重做日志就等于命令序列,数据库数据存储就等于状态机,唯一不同的是单机数据库日志序列化lock一下就可以做,那么多个参与者之间如何让日志序列化呢?这就是Paxos等一致性协议致力解决的具体问题,即如果状态机状态的改变是由命令1...N组成的,那么Paxos需要保证对任何一个1<=k<=N,命令序列的内容被系统中绝大部分的参与者同意。这个k可以称之为log position,log index,不同文章叫法不同。这里我们对上面问题一的一致性问题进行了具体化,只要保证了大部分参与者执行的命令序列是一样的,系统就是一致的。再具体化一步,保证命令序列中每个序号对应的命令是一样的,就能保证命令序列是一样的。Paxos的责任就是保证:在一个命令序列中,同一个序号下面对应的命令内容是一样的。[7]的描述还是比较清晰的。


问题三:Paxos如何保证多参与者同一个序号对应同样的命令内容

这是各类Paxos算法的核心,不过我认为在准备动手写代码前这是最不重要的一部分,因为除了最开始的paxos文章说的比较模糊,后面出来的都把这一块描述的异常清晰,甚至各种优化都帮着想好了。这里面理解下面几点就行,

  1. 目标:让第k个命令序号执行x命令(x比如是inc)

  2. 动作:给所有人发请求,<no, k, x>,no每次都要涨,这个好理解,否则一个网络上漂了半天的包被服务器收到怎么办?

  3. 结果:如果大部分参与者都同意,就确定了<k, add>的对应关系;否则,每个Paxos算法都有一系列的规则来让系统一定能达成一个共同的决议,具体参考每个算法;


问题四:leader选还是不选

网上见到有人争论basic paxos不用选leader,对运维更友好,对网络抖动容忍度高等等,这个更像是一个工程实现问题,而不是理论问题。在一个多参与者的系统里面,如果每个人都提议,那么显然冲突的概率是很大的,冲突了就要重新开始新一轮提议,这会导致很低效,就好像高速路上8车道变成了1车道,这时候谁先走就是一个问题,如果没有警察叔叔,必定乱成一锅粥,在一个高压力的系统中问题类似。选了一个leader之后,leader知道没人跟自己抢,就可以省不少事,事情省了,系统也简单了,这就是Raft的思路。同时,如果有了leader,批量确认命令序列也成了可能(否则同一个paxos group冲突肯定高的吓人,有了警察叔叔每个车道可以一次放行20辆,没有警察叔叔一次放20辆可能很快就会因为事故全部堵死),这就是multi-paxos,即一次确认多个命令。选leader不是没有弊端,如果leader挂了,这时候系统是不能服务的,必须等新的leader选出来,这个一般几百毫秒搞定。那么,leader挂的时候如何降低对服务的影响?就是将paxos group做的精细一点,一个leader挂了,只影响这个paxos group,其余正常服务。如果碰到leader节点网络抖动,也可以迅速切换,减小影响。整体来看,选leader是较好的做法,人类社会不也需要leader嘛。


问题五:机器down掉后,新加入的机器是否能立刻服务

这点取决于状态机如何维护,是整个系统作为一个状态机还是每个参与者都是一个独立的状态机。如果整个系统被当做一个独立的状态机,那么任何机器加入进来都可以立刻服务,因为系统的状态是完整的,这也是basic paxos能达到的效果。如果系统中每个参与者都被当做一个独立的状态机,那么任何新机器加入进来必须先从其他机器获得一个过去的状态(snapshot),类似数据库备份里面的数据文件,然后执行这个状态之后的命令,类似执行数据库重做日志,等到状态已经追赶上系统中的多数参与者,就可以提供服务,这是Raft的效果。从描述看,Raft似乎弱了点,但是本质上两个是类似的,因为basic paxos将整个系统视为状态机增加了复杂性,且在参与者连续down的场景中,一样不能很好的解决,也需要尽快让新机器追状态,以达到每个命令都有多replica。


问题六:paxos group如何随着新节点加入而改变

这个问题被称为view change,就是说参与者变多了,比如1 2 3变成1 2 3 4 5,或者参与者要换一批,比如 1 2 3换成4 5 6,这个问题Raft处理的最好,简洁明了,说简单点就是在新旧config交叠的时候,leader必须得到新旧两个group的认可,这就避免了多leader脑裂的问题。viewstamped replication第一版在变配的时候要停机,revised解决了这个问题;paxos make simple里面的N+alpha方案不太好懂,按照文中的描述,在极端情况下有正确性问题(练习题[10]里面最后的题目,当然,工程实现上可以绕,这本来就是一个低频动作)


问题七:不同方案哪个资源会首先成为瓶颈

在leader方案中,最容易成为瓶颈的是网络,因为从方案设计上使用的就不均衡,leader接受请求后转给其他参与者,出口带宽会承压,这时候可以选择chain forward,让其余参与者也承担网络流量。磁盘方面还好,毕竟都上paxos了,PCIe接口NVME SSD盘应该少不了,秒几十万写不是事,还有像Oceanbase[11]讲的,log落盘就返回的话磁盘更不是事。现在CPU也越来越强大,配合上各类专用处理器,牛的不行。


问题八:读的时候怎么保证一致性

这个问题在各个Paxos文章里面叙述的不太明显,其实是一个很难的工程问题。basic paxos里面没有专门提,我揣摩意思就是读跟写一样,走完整的多参与者决策流程,这个肯定能读到一致的数据,但是性能恐怕不会好。在leader选举的方案里面,也不是件简单的事情。直接读leader的话,因为leader可能是过期的,那么可能导致读到的数据是过期的,这时候又要给leader加上lease机制,而这个机制更进一步限制了leader挂时候的可用性恢复。这里或许提供两类接口是一个明智的选择,比如

1. 非一致读:可能读到过期数据,这时候读任何一个参与者都行,不过也不能太随便,client可以提要求,该参与者与leader的距离不能超过一个阈值或者已经apply到RSM的序列号至少得大于client曾经写过的命令序列号。

2. 一致读:只能读leader,或者为了负载均衡,leader选一个状态一致的参与者也行。



  1. 封面图片来自:https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Leslie_Lamport.jpg/220px-Leslie_Lamport.jpg

  2. http://research.microsoft.com/en-us/um/people/lamport/pubs/lamport-paxos.pdf

  3. http://101.96.10.62/www.pmg.csail.mit.edu/papers/vr-revisited.pdf

  4. https://zh.scribd.com/document/323523128/raft-pdf

  5. http://www.tcs.hut.fi/Studies/T-79.5001/reports/2012-deSouzaMedeiros.pdf

  6. http://research.microsoft.com/en-us/um/people/lamport/pubs/paxos-simple.pdf

  7. https://ramcloud.stanford.edu/~ongaro/userstudy/paxos.pdf

  8. https://ramcloud.stanford.edu/~ongaro/userstudy/raft.pdf

  9. https://ramcloud.stanford.edu/~ongaro/userstudy/paxossummary.pdf

  10. https://ramcloud.stanford.edu/~ongaro/userstudy/rubric.pdf

  11. https://www.zhihu.com/question/19841579/answer/131853733

以上是关于使用Paxos前的八大问题的主要内容,如果未能解决你的问题,请参考以下文章

太阳系和八大行星的英文介绍

百科知识 八大菜系是指哪八大菜系

诸葛亮 VS 庞统,拿下分布式 Paxos | 文末送书

八大算法思想

JAVA实现八大排序+二分查找

如何用STAR法则来回答「宝洁八大问」