Basic-Paxos协议日志同步应用
使用Basic-Paxos协议的日志同步与恢复
传统数据库保持服务持续可用通常采用1主N备, 既采取两种日志同步模式: Maximum Availability和Maximum Protection.
Maximum Availability 表示Primary尽力将redo同步到Standby之后返回client成功, 如果Standby宕机或者网络中断, 那么Primary将单独提供服务, 这意味着Primary单点运行, 或者在Primary故障的情况下, Standby将会出现redo gap, 可能发生数据丢失;
Maximum Protection 表示Primary一定将redo同步到Standby之后返回client成功, 这意味着任何Standby宕机活着网络中断的情况下Primary不得不等待Standby响应活着网络恢复;
很显然在传统的数据安全模式中, A和C很难取舍.
基于Paxos协议的数据同步与传统主备方式最大的区别在与Paxos只需任意超过半数的副本在线且相互通信正常, 就可以保证服务的持续可用, 且数据不丢失.
数据持久化需求:
- 在N个server的机群里, 持久化数据库或者文件系统的操作日志, 并且为每条日志分配连续递增的logID
- 允许多个客户端并发的向机群里的任意机器发送日志同步请求
- 在N个server中只要有超过半数的server(majority)正常服务, 并且相互通信正常, 那么这个机器就可以持续的提供日志持久化和查询服务
先回忆下Basic-Paxos的两个阶段:
第一阶段Prepare:
P1a. proposer发送提案请求
proposer生成一个全局唯一且递增的提案ID(n), 并且向集群内所有acceptor发送prepareRequest(这里无需携带提案内容, 只需要携带提案ID)
P1b. acceptor应答提案请求
acceptor会做出两个承诺, 一个应答.
两个承诺:
- 承诺不再应答提案ID<=n的prepareRequest
- 承诺不再应答提案ID<n的acceptRequest
一个应答:
- 返回acceptor已经应答的提案中提案ID最大的提案.
第二阶段Accept:
P2a. proposer发送提案应答
如果proposer接收到了集群中大多数acceptor响应的prepareRequest(ID=n), 那么proposer可以向集群内的所有acceptor发送acceptRequest(提案ID为n, 提案内容为v), 提案内容可以是提案中被接受的提案ID最大的提案内容, 或者自己可以随意决定提案内容.
P2b. acceptor应答提案应答
如果acceptor接收到提案ID为n的acceptRequest, 除非accepter已经应答了提案ID>n的acceptRequest, 否则accepter将会应答该提案应答.
将每条日志的持久化流程都看作一个Paxos Instance
, 不同的logID代表不同的Paxos Instance
形成的"决议(decision)". 即每一个logID标识着一轮完整paxos协议流程的执行, 最后形成decision. 机群内的每个server同时作为paxos的acceptor和proposer.
LogID
proposer get所有acceptor本地目前已写盘的maxlogID, 而只需收集到majority返回的结果, 并选择其中最大的logID+1作为proposer本次待持久化日志的logID.
这里并不能保证并发提交的两条日志一定被分配到不同的logID, 而需要依靠后续的paxos协议流程来达到对一个logID形成唯一的决议(decision)的目的.
ProposalID
获取LogID后, server作为proposer开始针对当前logID, 执行Paxos Instance, 先产生proposalID, 根据paxos协议的要求, proposalID要满足全局唯一且递增序, 即对同一个server来说后产生的proposalID一定大于之前产生的.
工程实现里可以使用高位timestamp, 地位server ip作为proposalID
Prepare阶段
proposer准备好proposalID后, 将proposalID作为"提案(proposal)"发送给所有的acceptor.
根据Paxos协议P1b的约束, 这个阶段发送的proposal并不需要携带日志内容, 而只需要发送proposalID. acceptor收到proposal后, 根据Paxos协议P1b判断是否要"回应(response)", 只有在这个Paxos Instance
内(即针对这个logID)没有response过proposalID大于等于当前proposal的, 并且也没有"接受(accept)"过proposalID大于当前proposal的, 才可以response, 并承诺不再accept那些proposalID小于当前proposal的.
如果已经accept过proposal, 那么连同proposalID最大(上次accept的提案)的日志内容一同response. 为了遵守P1b的约束, 在宕机恢复后也能满足, 因此在response前, 需要将当前proposalID写到本地磁盘.
上述Prepare阶段的处理流程暗示, 对于分配到相同logID的不同日志, 由于他们的proposalID不同, acceptor在response一个较小proposalID后, 是允许继续response后来的较大的proposalID的.
Accept请求阶段
proposer收集到majority的response后, 来决定后续是否将要发出的"accept请求(acceptRequest)", 判断如果majority的response中的日志内容都为空, 那么可以向所有acceptor发出acceptRequest并携带上当前日志内容; 而如果有任意的response中的日志内容有效, 那么说明当前logID已经被其他日志占用, 且其他日志可能已经在majority上持久化, 因此需要回退, 回到第一步"获取logID"重新执行.
Accept处理阶段
acceptor收到proposer的acceptRequest后, 根据上文中"Prepare阶段"的承诺, 判断当前logID下, 曾经response过的最大proposalID, 如果小于等于当前proposal的, 则可以继续执行后续的accept处理逻辑; 而如果大于当前proposal的, 则说明有logID且proposalID更大的proposal在并发执行, 当前proposal会被覆盖, 因此回复proposer要求回退到第一步"获取logID"重新执行.
然后accept处理逻辑将当前proposal连同proposalID一起写到本地磁盘, 给proposer回复成功. proposer收集到majority的回复成功后, 说明本条日志已经在机群上持久化成功, 可以保证后续一定不会被覆盖或丢失, 可以给客户端返回成功.
上述accept处理阶段的流程暗示, 可能会存在针对一个logID, 日志只在少于半数的acceptor上写到本地磁盘, 而acceptor同时response了proposalID更大的proposal, 而使得当前logID下没有任何日志在机群上持久化成功. 即一个logID可能没有标识任何有效日志, 这种情况是可以接受的.
日志内容读取
已经在机群上持久化成功的日志, 需要能够被读取出来, 一般的应用模式是按照logID的顺序依次读取并回放日志. 读取的时候针对每一条logID, 需要执行一轮完整的paxos协议流程, 将accept处理阶段成功的日志内容返回.
需要注意的是, 在accept请求阶段的处理逻辑变化: proposer收集到majority的response后, 判断如果majority的response中的日志内容都为空, 那么向所有acceptor发出日志内容为空的acceptRequest; 而如果有任意的response中的日志内容有效, 则选择proposalID最大的日志内容放入acceptRequest. 后续收到majority的accept回复成功后, 才可以返回日志内容作为读取结果.
这里的流程暗示, 针对一个logID, 如果之前已经有日志内容持久化成功, 那么这条日志一定会被选为acceptRequest; 而如果之前日志内容仅仅在小于半数的server上写到磁盘, 那么最终这条logID的内容有可能是有效日志, 也有可能内容为空.
参考:
http://research.microsoft.com/en-us/um/people/lamport/pubs/paxos-simple.pdf
http://www.cs.cmu.edu/~pavlo/courses/fall2013/static/papers/p398-chandra.pdf
http://codemacro.com/2014/10/15/explain-poxos/
http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=403582309&idx=1&sn=80c006f4e84a8af35dc8e9654f018ace&3rd=MzA3MDU4NTYzMw==&scene=6#rd
http://oceanbase.org.cn/?p=90
http://mp.weixin.qq.com/s?__biz=MjM5MDg2NjIyMA==&mid=203607654&idx=1&sn=bfe71374fbca7ec5adf31bd3500ab95a&key=8ea74966bf01cfb6684dc066454e04bb5194d780db67f87b55480b52800238c2dfae323218ee8645f0c094e607ea7e6f&ascene=1&uin=MjA1MDk3Njk1&devicetype=webwx&version=70000001&pass_ticket=2ivcW%2FcENyzkz%2FGjIaPDdMzzf%2Bberd36%2FR3FYecikmo%3D
http://static.googleusercontent.com/media/research.google.com/zh-CN//archive/chubby-osdi06.pdf