paxos协议更新日志
基于Paxos协议的数据同步与传统主备方式最大的区别在与Paxos只需任意超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失。
Basic paxos协议更新日志
我们将数据持久化的需求抽象为:在N个server的机群上,持久化数据库或者文件系统的操作日志,并且为每条日志分配连续递增的logID,我们允许多个客户端并发的向机群内的任意机器发送日志同步请求。
将每条日志的持久化流程都看作一个“Paxos Instance”,不同的logID代表不同的Paxos Instance形成的“决议(decision)”。即每一个logID标识着一轮完整paxos协议流程的执行,最后形成decision。机群内的每个server同时作为paxos的acceptor和proposer。
获取LogID
Server收到客户端的持久化日志请求后,因此向所有acceptor查询它们本地目前已写盘的最大logID,而只需收集到majority返回的结果,并选择其中最大的logID+1作为本次待持久化日志的logID。
从上面的描述可以看出,这里并不能保证并发提交的两条日志一定被分配到不同的logID,而是依靠后续的paxos协议流程来达到对一个logID形成唯一的decision的目的。
产生ProposalID
这里我们使用server的timestamp联合ip作为proposalID,其中timestamp在高位,ip在低位。(为了唯一卫衣proposalID,只要要求时钟的误差范围小于server重启的时间)
Prepare阶段
只有在这个Paxos Instance内(即针对这个logID)没有response过proposalID大于等于当前proposal的,并且也没有“接受(accept)”过proposalID大于当前proposal的,才可以response,并承诺不再accept那些proposalID小于当前proposal的。
上面Prepare阶段的处理流程暗示,对于分配到相同logID的不同日志,由于他们的proposalID不同,acceptor在response一个较小proposalID后,是允许继续response后来的较大的proposalID的。
Accept请求阶段
如果majority的response中的日志内容都为空,那么可以向所有acceptor发出accept request并携带上当前日志内容;而如果有任意的response中的日志内容有效,那么说明当前logID已经别其他日志占用,因此需要回退,回到第一步“获取logID”重新执行。
Accept执行阶段
而如果ProposalID小于当前最大minProposal的,则说明有logID切proposalID更大的proposal在并发执行,当前proposal会被覆盖,因此回复proposer要求回退到第一步“获取logID”重新执行。
这里的流程暗示,针对一个logID,如果之前已经有日志内容持久化成功,那么这条日志一定会被选为accept request;而如果之前日志内容仅仅在小于半数的server上写到磁盘,那么最终这条logID的内容有可能是有效日志,也有可能内容为空。(本例中可能两个提议者竞争一个logID,然后本例中为了加快收敛,其中一个自动放弃,选择更大的logID)
日志内容读取
在读取的时候也需要回放一遍paxos协议,防止读到未提交的日志(相当于raft的提交阶段?)。
为什么需要comfirm日志
假设有a, b, c 3个节点, 刚开始的时候, 3个节点的值是一致的, 都是v1. 这时候一个proposer发起一轮paxos请求, 希望将值设置成v2. 那么可能出现两种情况, 一种是paxos成功了, a, b, c的多数派中value设置成了v2, 也就是说v2被批准了(假设a, b, c的值分别是v1, v2, v2). 另外一种是失败了, a, b, c的多数派中value仍然是v1, 也就是说v2没有被批准, 但是a, b, c中可能存在少数派节点的值是v2(假设a, b, c的值分别是v1, v1, v2). 按照p2a的流程, 选取proposal的原则是选取多数派中, proposal号最大的作为期望被批准的value. 在上述两种情况下, 当reader读取数据时, 按照p2a的逻辑, 既可能读到v1, 也可能读到v2, 那这样的话, 如果有一个acceptor故障了, 其实reader就无法准确知道之前被批准的value了吧? 我看paxos made simple的论文中也提到, 如果有一个acceptor故障了, 也不可能找出被批准的value了, 唯一的办法就是issue a proposal, 然后运行一轮新的paxos算法了。这是不是说, 不管reader读到的是v1还是v2, 仍然发起一轮paxos协议, 保证一致性就ok了
简而言之,就是只有leader某条日志才知道某条日志复制到大多数,而参与者并不知道。所以在提交的时候,要么再跑一次paxos,要么写一条comfirm日志
Multi-paxos更新日志
Leader的产生
通过Multi-paxos,我们可以简化掉产生logID阶段和prepare阶段,而是由唯一的leader产生logID,然后直接执行accept,得到多数派确认即表示redolog同步成功。
首先,需要明确的是Multi-Paxos协议并不假设全局必须只能有唯一的leader来生成日志,它允许有多个“自认为是leader的server”来并发生成日志,这样的场景即退化为Basic-Paxos。
Leader产生并不是走完一个完整的basic paxos流程,而是只走了proposal prepare阶段,所以可能同时产生多个leader。因此,我们需要先写一条StartWorking日志,成功写下这条日志升级为唯一leader
confirm日志优化
因为在读取日志的时候,需要再进行一次basic paxos协议。因此引入confirm日志,针对刚刚提交的日志写入一条confirm日志。出于性能考虑,实际操作中,批量发送confirm日志,因此,读到未确认的日志,还是需要走一遍paxos协议
新任leader对日志的重确认
新任leader可能保存的日志落后于前任leader,因此需要对小于当前集群中max log id的日志都进行,只要大多数回复max log id即可。这样的结果可能超越了前任已经accept的日志记录,称为最大commit原则。
“幽灵复现”日志的处理
使用Paxos协议处理日志的备份与恢复,可以保证确认形成多数派的日志不丢失,但是无法避免一种被称为“幽灵复现”的现象,如下图所示:
| x | Leader | A | B | C |
|---|---|---|---|---|
| 第一轮 | A | 1-10 | 1-5 | 1-5 |
| 第二轮 | B | 宕机 | 1-6,20 | 1-6,20 |
| 第三轮 | A | 1-20 | 1-20 | 1-20 |
第一轮中A被选为Leader,写下了1-10号日志,其中1-5号日志形成了多数派,并且已给客户端应答,而对于6-10号日志,客户端超时未能得到应答。
第二轮,A宕机,B被选为Leader,由于B和C的最大的logID都是5,因此B不会去重确认6-10号日志,而是从6开始写新的日志,此时如果客户端来查询的话,是查询不到6-10号日志内容的,此后第二轮又写入了6-20号日志,但是只有6号和20号日志在多数派上持久化成功。
第三轮,A又被选为Leader,从多数派中可以得到最大logID为20,因此要将7-20号日志执行重确认,其中就包括了A上的7-10号日志,之后客户端再来查询的话,会发现上次查询不到的7-10号日志又像幽灵一样重新出现了。
对于将Paxos协议应用在数据库日志同步场景的情况,“幽灵复现”问题是不可接受,一个简单的例子就是转账场景,用户转账时如果返回结果超时,那么往往会查询一下转账是否成功,来决定是否重试一下。如果第一次查询转账结果时,发现未生效而重试,而转账事务日志作为幽灵复现日志重新出现的话,就造成了用户重复转账。
为了处理“幽灵复现”问题,我们在每条日志的内容中保存一个generateID,leader在生成这条日志时以当前的leader ProposalID作为generateID。按logID顺序回放日志时,因为leader在开始服务之前一定会写一条StartWorking日志(先同步再写StarWorking日志),所以如果出现generateID相对前一条日志变小的情况,说明这是一条“幽灵复现”日志(它的generateID会小于StartWorking日志),要忽略掉这条日志。
其中,log1和log6分别是第一轮和第二轮的start working log。
本质上是通过在发生leader权抢占的时候,ProposalID的递增性质保证了不会回放以前的logID。
multi-paxos和raft对比
以下是我自己的观点,不保证正确性
- raft logID递增,multi_paxos并不需要
- multi_paxos为了保证读到的日志已经提交,需要再走一边paxos确认日志;raft每次获得多数派的认可后,也需要向参与者发送提交命令(相当于读取命令)。
- 因为multi-paxos的logID不连续,在leader权抢占的时候,所以有了最大commit原则,最大commit原则可能产生幽灵日志,如果epochID小于上一条,就不回放,所以有了不回放上一个任期的日志。
paxos协议更新日志的更多相关文章
- Paxos协议理解
第三次报告: 理解Paxos协议 一. Paxos协议背景 什么是Paxos协议? 一般地,从客户端和服务器的角度,任何一个分布式系统都可以理解成由一个服务器集合和一个客户端集合组成,一个或多个客户端 ...
- Easy Sysprep更新日志-skyfree大神
Easy Sysprep更新日志: Skyfree 发表于 2016-1-22 13:55:55 https://www.itsk.com/forum.php?mod=viewthread&t ...
- Paxos协议超级详细解释+简单实例
转载自: https://blog.csdn.net/cnh294141800/article/details/53768464 Paxos协议超级详细解释+简单实例 Basic-Paxos算法 ...
- Paxos协议笔记
对Paxos协议的介绍,可以通过Leslie Lamport的<Paxos Made Simple>展开学习和了解.Paxos算法在允许失败的分布式系统环境下,实现系统一致性.失败的情况有 ...
- [实战]MVC5+EF6+MySql企业网盘实战(29)——更新日志
摘要 NetDisk更新日志,及项目使用说明. 开发工具 Vs2013+mysql+ef6+mvc5 bug 1.在加载列表的时候,默认加载的所有,修改为,过滤逻辑删除的文件. 2.加载音乐,文档等分 ...
- AgileEAS.NET SOA中间件平台更新日志 2015-04-28
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- python解析git log后生成页面显示git更新日志信息
使用git log可以查到git上项目的更新日志. 如下两个git项目,我想把git的日志信息解析成一个便于在浏览器上查看的页面. https://github.com/gityf/lua https ...
- 更新日志 - fir.im「高级统计」功能上线
距离 2016 年到来只剩 10 个日夜,fir.im 也准备了一些新鲜的东西,比如「高级统计」功能和「跳转应用商店」功能,帮助你更好地管理.优化应用,欢迎大家试用反馈:) 新增高级统计功能 这次更新 ...
- 更新日志 - fir.im Jenkins & Gradle 插件上线
最近 fir.im 工程师们效率爆表,fir.im 实用工具集合又添加了新的成员-- Jenkins & Gradle 插件,让 App 打包上传更加简单快速. fir.im Jenkins ...
随机推荐
- 团队作业(HCL队)第三周—需求改进和系统分析
2.需求&原型改进: 1.问题:游戏中坦克的移动和攻击怎么控制的? 改进: 在游戏中,我控制我方坦克,按下方向键坦克便向按下的方向移动,按下Z键,我方坦克发射炮弹.敌方坦克面向随机的方向移动, ...
- Elasticsearch 在 windows 和 ubuntu 下详细安装过程
1. 前言 作为一名 .NET 平台开发者,选择开发框架时总会面临更多的局限性,不过对于搜索这种刚需服务来说,开源框架可供选择的余地还是比较大的.笔者之前用的是 Lucene.net ,现在深感其使用 ...
- Microsoft.Office.Interop.Excel 导出Excel
; ; /// <summary> /// 使用 Excel.dll 导出 Excel /// </summary> /// <param name="list ...
- 记录一下获取浏览器可视区域的大小的js
function GetPageSize() { var xScroll, yScroll; if (window.innerHeight && window.scrollMaxY) ...
- 在循环中使用鼠标悬停时表示当前悬停选中,传入this关键字即可
在前端循环中使用鼠标悬停事件 <div class="message-widget contact-widget"> <!-- Message --> {% ...
- VS2017集成FastReport.Net并将模板保存到数据库
本着开发与实施分离的思想,设计一个通用的报表设计窗体显得尤为重要(下图为图一): 要求与优点: I.报表设计窗体支持所有单据调用,一种单据支持多个打印模板. II.报表模板存储在数据库中.一是支持客户 ...
- Day 31 面向对象考试题 第四次考试.
一 基础知识和函数: 1.文件操作有哪些模式?请简述各模式的作用 r ,只读模式[默认模式,文件必须存在,不存在则抛出异常] w,只写模式[不可读:不存在则创建:存在则清空内容] x, 只写模式[不可 ...
- Day 29 _模块二 -hashlib_configparse_logging
一.hashlib Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数 ...
- php主要用于哪几方面
1,服务端脚本,网站和web应用程序,web服务器,php解析器,web浏览器 2,命令行脚本 3,编写桌面应用程序
- java获取当前文件路径的方法
第一种: File f = new File(this.getClass().getResource("/").getPath()); System.out.println(f); ...