转载原文:
http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=403582309&idx=1&sn=80c006f4e84a8af35dc8e9654f018ace&3rd=MzA3MDU4NTYzMw==&scene=6#rd
Paxos 协议简单回顾
主备方式处理数据库高可用问题有上述诸多缺陷,要改进这种数据同步方式,我们先来梳理下数据库高可用的几个基本需求:
-
数据不丢失
-
服务持续可用
-
自动的主备切换
使用Paxos协议的日志同步可以实现这三个需求,而 Paxos 协议需要依赖一个基本假设,主备之间有多数派机器(N / 2 + 1)存活并且他们之间的网络通信正常,如果不满足这个条件,则无法启动服务,数据也无法写入和读取。
我们先来简单回顾一下 Paxos 协议的内容,首先,Paxos 协议是一个解决分布式系统中,多个节点之间就某个值(提案)达成一致(决议)的通信协议。它能够处理在少数派离线的情况下,剩余的多数派节点仍然能够达成一致。然后,再来看一下协议内容,它是一个两阶段的通信协议,推导过程我就不写了(中文资料请参考这篇 Http://t.cn/R40lGrp ),直接看最终协议内容:
1、第一阶段 Prepare (Proposer:PrepareRequest , Acceptor:PrepareResponse)
P1a:Proposer 发送 Prepare
Proposer 生成全局唯一且递增的提案 ID(Proposalid,以高位时间戳 + 低位机器 IP 可以保证唯一性和递增性),向 Paxos 集群的所有机器发送 PrepareRequest,这里无需携带提案内容,只携带 Proposalid 即可。
P1b:Acceptor 应答 Prepare
Acceptor 收到 PrepareRequest 后,做出“两个承诺,一个应答”。
两个承诺:
-
第一,不再应答 Proposalid 小于等于(注意:这里是 <= )当前请求的 PrepareRequest;
-
第二,不再应答 Proposalid 小于(注意:这里是 < )当前请求的 AcceptRequest;(用于二阶段确认)
一个应答: PrepareResponse
-
返回自己已经 Accept 过的提案中 ProposalID 最大的那个提案的内容,如果没有则返回空值;
注意:这“两个承诺”中,蕴含两个要点:
-
就是应答当前请求前,也要按照“两个承诺”检查是否会违背之前处理 PrepareRequest 时做出的承诺;
-
应答前要在本地持久化当前 Propsalid。
2、第二阶段 Accept (Proposer:AccpetRequest , Acceptor:AcceptResponse )
P2a:Proposer 发送 Accept
“提案生成规则”:Proposer 收集到多数派应答的 PrepareResponse 后,从中选择proposalid最大的提案内容,作为要发起 Accept 的提案,如果这个提案为空值,则可以自己随意决定提案内容。然后携带上当前 Proposalid,向 Paxos 集群的所有机器发送 AccpetRequest。
P2b:Acceptor 应答 Accept
Accpetor 收到 AccpetRequest 后,检查不违背自己之前作出的“两个承诺”情况下,持久化当前 Proposalid 和提案内容。最后 Proposer 收集到多数派应答的 AcceptResponse 后,形成决议。
这里的“两个承诺”很重要,后面也会提及,请大家细细品味。