paxos 算法实现和设计要点


先想到的几个点

1. 用了fast Paxos, 只有一个leader(master,coordinator).  如果leader fail(单点),那么新的master需要选举。  master选举本身也是个 basic paxos instance, 所以多个节点都请求为master,这里多个节点都扮演了proposer(不是fast paxos了), 这就是普通的paxos算法了.

2.  Phase 2 中如果有收到acceptor 返回的值,那么必须使用其序列号最高的那个值。

3.  Paxos Group replica直接的连接维护: 如果是FC,那么使用connection事件;如果以太网连接,那么必须去polling/ping 对方的机器。其实这里问题很多。

3.1  节点间的连接状态是否要维护在所有的节点上还是就master上。 个人觉得应该在所有的节点上。

3.2  如何处理网络的transient ?

3.3 网络出问题。 集群被隔成几个小集群,互相不能通信了。 某两台机器之间不能连接了。

4. 假设用basic paxos,  有proposer 1, proposer 2和 proposer 3,他们先后发出一轮(one epouch) paxos, 分别是instance 1, instance 2, instance 3, 然后instance 1已经accept 了 proposal from proposer 1 ,  acceptor 2 在想 accept proposal from proposer 1之前promise了 proposal from instance 2 然后accept了proposal frominstance 3 但是在proposer 1和proposer 2获得多数派的acknowledge之前被proposer 3的proposal 抢占了。 所以, proposer 3 的paxos Instance 3会得到不同的值,但是不幸的是在instance 3 达到多数派回复之前,instance 1 达到多数派了,但是按paxos 协议,instance 3选取的是 instance 2 的值啊。  

    所以这里问题是, acceptor回复的是自己之前accept过的值和epoch号还是 回复自己之前accept过且已经被多数派accept也就是说已经choosed的值啊 ???????????


5. Proposal是 单个的还是批量的,单个的话会导致效率问题,批量的话又如何组织呢 ?

6. Learner的可以由proposer/master来担任, master如果故障那么learner也故障,反之也一样,而master的单点故障已经有master lease和paxos选举解决了。

7. 选举quorum也即是replica 多数派的确定。 最好是可以动态管理的。


参考chubby

1. sector 4.1):

用了fast paxos, 只有一个leader(master,coordinator).  如果leaderfail(单点),那么新的master需要选举。  master选举本身也是paxos instance, 所以多个节点都请求为master,这里多个节点都扮演了proposer(不是fast paxos了), 这就是普通的paxos算法了,这样就需要解决两个工程问题:

1.1 编号的全局性通过取模偏序编号解决;

1.2  如果有已经有accept的coordinator,一个instance会有多个round,那么新的propser最新一次propose必须使用编号最高的值,如果通过那么这儿proposer就是新的coordinator.  其实就是下面方案2的情况。

收到多数派的promise

根据包含的value不同,这些promise又分三种情况:

  • 多数派的value是相同的,说明之前已经达成了最终决议
  • value互不相同,之前并没有达成最终决议
  • 返回的value全部为null

全部为null的情况比较好处理,只要proposer自由决定value即可;多数派达成一致的情况也好处理,选择已经达成决议的value提交即可,value互不相同的情况有两种处理方式:

  • 方案1:自由确定一个value。原因:反正之前没有达成决议,本次提交哪个value应该是没有限制的。
  • 方案2:选择promise编号最大的value。原因:本次选举(instance)已经有提案了,虽未获通过,但以后的提案应该继续之前的,Lamport在paxos simple的论文中选择这种方式。

其实问题的本质是:在一个instance内,一个acceptor是否能accept多个value?约束P2只是要求,如果某个value v已被选出,那之后选出的还应该是v;反过来说,如果value v还没有被多数派accept,也没有限制acceptor只accept一个value。

感觉两种处理方式都可以,只要选择一个value,能在paxos之后的过程中达成一致即可。其实不然,有可能value v已经成为了最终决议,但acceptor不知道,如果这时不选择value v而选其他value,会导致在一次instance内达成两个决议。


2.   sector 4.2)

2.1 如果有的节点比较慢,或者故障过,那么最近几次的paxos instance可能missed, so A catch-up mechanism is used to catch up with the master replica.

2.2 Each replica has the persistent log to record all paxos behavior. So one instance requires a sequence of 5 writes( for each of the propose, promise, accept, acknowledgement and commit(这里或许该learn)) to disk. The disk flush can dominate the overall latency of the system. So has to reduce it. 

   This is achieved by ignore Propose message or promise step because Master ID does not change between instances in fast paxos, becuase only one proposer is master. So no live lock here.  With this optimization, only one write to disk per instance on each replica.  The master writes to disk immediately after sending its accept
message and other replicas write to disk prior to sending their acknowledge message.


3. 硬盘错误处理,persistent log

可能发生文件内容被改变也可能是文件不访问。 内容改变检查的话用checksum of content的方法。 要区分是文件不可访问还是带着空盘的新节点,chubby用的是GFS maker, 这你可以用其他方法。 

发生错误的节点得用catchup方法尽快同步到最新状态,期间算作paxos机器的一部分,但是不参加选举。这样既可以维护paxos的完整性又可以降低系统延迟。


4. Master Lease

基本是为了让replicas知道master还活着,更进一步可以让master知道replica还活着,这样master可以转让部分读取请求给replica。

一个lease,一个租约,本质上是个定时器。 到期了就得更新,否则无效。 replica给之前的当然现在也活着master发送一个lease,期间replica拒绝任何来自其他节点paxos消息(propose, accept),lease快过期的时候,master向replica申请更新租约。  在实现上,master上的lease时间跨度比replica上的lease短一点点,这样是为了避免系统时钟频率漂移导致的误差。 这有力的保证了,老master lease失效前,新master不会产生。这样client不会向老的master发生读取请求。 


paxos算法本身保证了数据在各个节点一致性,另外把lease 概念扩展到普通的relica上,这样可以让普通的replica 服务读取请求。 这样可以大大提高性能,毕竟在有些场景中读取远远比写来的多。


如果在一个网络不稳定环境,master会暂时性的失去连接,那么新的master会被选举并工作,新的master会来维护sequence number在多个paxos 实例之间。 但是老的master 回来后,尝试连接成功后会发起新的paxos 实例并且以更高的sequence number来抢回master位置(这里开始不理解了,不是有lease机制保证只有一个master吗? 老的master回来后发现lease应该expire了啊,那么replicas会拒绝来自老的master的paxos消息啊 ???)。 所以建议,master要经常去提高sequence number,  就是有事没事的就去提高一下。


这里引发了工程中的现实问题,master如何fail over到新的master, 这里的租约机制只说明了如何防止一个新的master的产生在老master过期之前,但是没有提及如何选举产生新的master, client如何知道新的master IP.  我这里提出很多问题

  •   譬如原来7个replica互相联通,某个为master,突然网络问题,3 replica互联,另外四个互联,这个时候为保证多数派一致性,必须选用4个节点集群担任新的paxos集群,但是4个节点在分裂为2对2呢 ? 或者master被完全隔离与网络之外。 
  • 新选出的master如何通知client, 假设简单的socket通知。或者采用client提交read 请求的时候,老的master的告诉client 他lease过期, 然后client随机去请求一个replica,直到选举新master的quorum中的replica告诉client新master的IP。
  • lease机制导致了 lease时间内无法选举产生新的master。 这一点SVC比 chubby强,SVC 不用paxos算法选举新的master。 而是网络连接地图会维护网络连接状态,他直接选举多数派中的第一个节点为 master。


5.  sector 5.4 Group membership, sector 5.5 Snapshots  and 5.6 Database transactions


Group membership 变更问题,本文没有透露。 可惜。 不过我觉得需要一层连接地图层。

Snapshots 是为了catchup 变快,和 记录paxos 动作的磁盘不够大时候。 paxos决议本质上是对一些数据结构进行操作的 状态机命令。可以对数据结构进行快照,然后把老的日志数据清除, 但是Paxos本身不知道具体的应用的数据结构,所以应用程序进行snapshot.

然后replica恢复的时候,从snapshot + snapshot之后的日志进行恢复,然后再向leader replica申请 leader的snapshot 和日志。

chubby的状态最终都维护在那个 fault-tolerant DB上,所以对DB的一些操作进行封装。 诸如insert,delete,lookup,原子性的cas(compare and swap)等操作, 其中 CAS操作是具有原子性的,所以进行简单封装可以模拟数据库事务,这个非常有用。 我们采用针对整个数据库的snapshot以及应用在该snapshot之上的数据库操作日志,实现了一个log-structured设计。操作日志就是Paxos日志。该实现会周期性地对数据库进行snapshot,以及进行相应日志的截断。



6.  sector ) Software Engineering

高效的算法表示: 容错算法本就是很难正确地进行表达,即使是以伪代码的形式。在当算法的代码是与其他代码共同构建一个完整系统的时候,情况会更糟。核心算法的阅读,理解,或者是在出现bug时的debug都变得更加困难。 我们相信选择一种描述语言,与和系统其它部分揉合在一块的显式代码实现相比,要更容易对状态机进行推导和修改。

运行时一致性检查:虽然算法正确,但是人为错误、代码bug会导致系统不一致, 所以工程上添加周期性的数据库一致性检查。Master周期性地提交一个针对数据库日志的checksum请求{!与读写请求一样,该请求也会被串行化,这样就可以保证它是对所有副本的相同状态计算的checksum}。 每个副本计算的checksun 会和master发过来的checksum进行比较,如果不一致则.....

测试:

并发性:总之,我们认为通过限制并发性来保证执行的可重复性,是一个正确的目标。不幸的是,产品的发展使得我们无法一直保持这些目标。






你可能感兴趣的:(实现,paxos,一致性)