理解Paxos Made Practical

来源:互联网 发布:python科学计算 豆瓣 编辑:程序博客网 时间:2024/06/06 02:37

Paxos Made Practical 
当一个组中一台机器提出一个值时,其他成员机器通过PAXOS算法在这个值上达成一致。 
Paxos分三个阶段。 
第一阶段: 
提出者会选出一个提议编号n(n>0,n的低位应当包含提出者的唯一标识,这样两台机器就不会产生相同的编号),然后会向组内其他成员发送信息PREPARE(n)。成员如果已经见到过PREPARE信息大于n,就会拒绝它;如果已经见到的PREPARE信息n‘ < n(这个提议n’的值假设为v‘),就会回复信息PREPARE-RESULT(n’, v’);如果这个成员还没有见过任何提议,就会回复信息PREPARE-RESULT(0, nil)。如果组内大多数成员(majority)都接受了这个PREPARE(n)信息,就进入PAXOS算法的第二阶段。

第二阶段: 
It sets v to the value in the highest-numbered prepare-result it received. If v is nil, it selects any value it wishes for v.(没看懂) 
接下来提议者会向其他成员广播消息PROPOSE(n,v)。同样,如果成员已经见过的PREPARE(n‘’)(确定是PREPARE而不是PROPOSE),n‘’ > n,就会拒绝这个消息;否则,就会接受这个消息,并给提议者一个回复。如果组内多数(包括提议者自己)都接受了这个PROPOSE消息,提议者会广播消息DECIDE(n,v),这就表示这个组在提议的值v上已经达成一致了。

第三阶段哪里去了?


下面是PAXOS算法在实际中是如何实现的。 
先来了解一下什么是状态机(state machine):是一个能接收请求产生回复的可确定性服务(deterministic service),可确定性服务意思是如果两个状态机拥有相同的初始状态,那么当它们接收到相同序列的请求时会产生相同的回复。

首先,我们要清楚一个复制系统(replication system),如Columbia University的M-SMR,会提供两套库,服务器端(server-side)库和客户端(client-side)库,前者负责状态机的实现,后者是让客户端发送请求给状态机然后得到回复。 
让我们具体看看服务器端(server-side)库提供的三个函数: 
替代文字 
这里说一下run函数的第三个参数 
buf execute (buf request); 
这是状态机里一个很重要的组成函数,它负责将请求带给状态机并返回回复。 
之前我们说过客户端库负责用户请求的提交和得到回复(这怎么和服务器端函数run的参数execute函数的功能一致呢?),假如这时有多个用户请求同时到来,客户端库就需要对这些请求达成一个统一的执行顺序让组内成员去执行,来保证一致性,这里就涉及与组内成员的通信问题。客户端库是如何来联系组内各个成员的?或许是RPC。 
不幸的是并不是所有的RPC服务器都是确定性的(deterministic)。举个例子,一个文件服务器会在一个文件发生写操作后将修改时间记录在文件的inode中,这样即使两个成员机器运行同样的文件服务器程序并执行相同的写请求,但是它们在执行写操作的时间却无法保证相同,比如都是2014/11/14 23:06。这样就会在成员之间出现分歧状态。为什么你记录的修改时间比我早十分钟?解决方法是让一个机器记录下自己的修改时间,然后广播给大家,告诉大家都来记录这个时间。其实这里修改时间就是一个不确定性值(non-deterministic value)。还是那个问题客户端库是通过什么手段来联系组内各个成员的? 
看来这个问题是无法解答了,解析来切入正题: Normal-case operation


Normal-case Operation 
在一个组里,有一个primary,其他的称作backups,这里有一个术语:view,表示一个拥有primary机器的处于活动状态的机器集合。每一个view会有一个view-id来唯一标识,而且view-id是单调递增的,随着每一次view的改变。 
替代文字

上图展示了在正常情况(没有机器加入,没有机器故障)下信息的流动。这里再引入一个术语:viewstamp,由view-id和timestamp结合而来,primary会给每一个到来的请求一个timestamp,这个timestamp就指明了请求被执行的顺序。同样加强版的viewstamp也表示请求的执行顺序。

0 0
原创粉丝点击