使用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

Basic-Paxos协议日志同步应用的更多相关文章

  1. Multi-Paxos协议日志同步应用

    使用Multi-Paxos协议的日志同步与恢复 基于Basic-Paxos协议的日志同步方案, 所有成员的身份都是平等的, 任何成员都可以提出日志持久化的提案, 并且尝试在成员组中进行持久化. 而在实 ...

  2. gap lock/next-key lock浅析 Basic-Paxos协议日志同步应用

    http://www.cnblogs.com/renolei/p/4673842.html 当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将 ...

  3. gap lock/next-key lock浅析Basic-Paxos协议日志同步应用

    http://www.cnblogs.com/renolei/p/4673842.html 当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将 ...

  4. paxos协议更新日志

    基于Paxos协议的数据同步与传统主备方式最大的区别在与Paxos只需任意超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失. Basic paxos协议更新日志 我们将数据持久 ...

  5. 理解分布式一致性:Paxos协议之Basic Paxos

    理解分布式一致性:Paxos协议之Basic Paxos 角色 Proposal Number & Agreed Value Basic Paxos Basic Paxos without f ...

  6. 理解分布式一致性:Paxos协议之Multi-Paxos

    理解分布式一致性:Paxos协议之Multi-Paxos Multi-Paxos without failures Multi-Paxos when phase 1 can be skipped Mu ...

  7. Paxos 实现日志复制同步(Basic Paxos)

    Paxos 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频 ...

  8. Paxos 实现日志复制同步

    Paxos 实现日志复制同步 本篇文章以 John Ousterhout(斯坦福大学教授) 和 Diego Ongaro(斯坦福大学获得博士学位,Raft算法发明人) 在 Youtube 上的讲解视频 ...

  9. Paxos 实现日志复制同步(Multi-Paxos)

    Paxos 实现日志复制同步 这篇文章以一种易于理解的方式来解释 Multi-Paxos 的机制. Multi-Paxos 的是为了创建日志复制 一种实现方式是用一组基础 Paxos 实例,每条记录都 ...

随机推荐

  1. python学习总结------邮件与短信

    邮件发送 - 简介: - 邮件服务器.用户名.密码 - 相关协议: - SMTP:简单邮件传输协议 - POP3:邮局通讯协议 - IMAP:交互式邮件存取协议 - SMTP协议默认端口是25 - 用 ...

  2. P4332三叉神经树

    题面 \(Solution\) 通过模拟,我们会发现每次修改 \(x\),只会改变从 \(x\) 向上一段连续的链的输出. 例如将 \(x\) 点从 \(0\) 改为 \(1,\) 那么它会影响从它向 ...

  3. 当我们在安装tensorflow时,我们在安装什么?- Intro to TF, Virtualenv, Docker, CUDA, cuDNN, NCCL, Bazel

    (Mainly quoted from its official website) Summary: 1. TensorFlow™ is an open source software library ...

  4. Spark实战练习01--XML数据处理

    一.要求 将XML中的account_number.model数据提取出来,并以account_number:model格式存储 1.XML文件数据格式 <activations> < ...

  5. STL应用——hdu1412(set)

    set函数的应用 超级水题 #include <iostream> #include <cstdio> #include <algorithm> #include ...

  6. [整理]修改git 默认编辑器为vim

    git config --global core.editor vim

  7. 《学习OpenCV》课后习题解答9

    题目:(P126) 创建一个程序,使其读入并显示一幅图像.当用户鼠标点击图像时,获取图像对应像素的颜色值(BGR),并在图像上点击鼠标处用文本将颜色值显示出来. 解答: 本题关键是会用cvGet2D获 ...

  8. PokeCats开发者日志(四)

      现在是PokeCats游戏开发的第八天的上午,感觉游戏做得差不多了,来写一下开发者日志吧!   (1)增加闯关模式,一共30关.   (2)更改了最后一关的主题,更换了背景,将树桩改为礼物盒.   ...

  9. 基于C#的PISDK研究(理论)

    本篇文章主要对PISDK体系结构以及重点类进行阐述. 当我们决定使用PISDK时,可能会使用到下面的类库: 在上表中,PISDK.dll为核心类,大部分主要功能都在该类中.PISDKCommon.dl ...

  10. java csv list cant not repeat

    require: /** * before: * file A1.csv {1,2,3,4,5} * file A2.csv {2,3,9,10,11} * file B1.csv {5,12,13, ...