paxos和分布式系统

1.paxos解决的问题
用来确定一个不可变变量的取值,取值可以是任意二进制数据,该变量的取值一旦确定将不再更改,并且可以被获取到(不可变性,可读取性)
2.分布式存储系统中paxos应用:
<1>数据本身可变,采用多副本进行存储
<2>多个副本的更新操作序列【Op1,Op2,…,Opn】是相同的,就变的
<3>用Paxos依次来确定不可变变量Opi的取值(即第i个操作是什么)
<4>每确定完Opi之后,让各个数据副本执行Opi,依次类推
3.Paxos解决一致性问题概述:
<1>设计一个系统,用来存储名称为var的变量
a.系统内部由多个Acceptor组成,负责存储和管理var变量
b.var的取值可以是任意二进制数据
c.系统对外的API库接口为:propose(var,V)
<2>系统需要保证var的取值满足一致性
a.如果var的取值没有确定,则var的取值为null
b.一旦var的取值确定,则不可被更改。并且可以一直获取到这个值
<3>系统需要满足容错特性
a.可以容忍任意proposer机器出现故障
b.可以容忍少数Acceptor故障(半数以下)
4.proposer并发执行问题:
假设系统由单个Acceptor 组成.通过类似互斥锁机制,来管理并发的proposer运行
Proposer首先向acceptor申请acceptor的互斥访问权,然后才能请求Acceptor接受自己的值
Acceptor给proposer发放互斥访问权,谁申请到互斥访问权,就接收谁提交的值
让proposer按照获取互斥访问权的顺序依次访问acceptor
一旦Acceptor接收了某个Proposer的取值,则认为var取值确定,其他Proposer不再更改
5.确定一个不可变变量取值-方案1
<1>实现基于互斥访问权的Acceptor的实现
Acceptor保存变量var和一个互斥锁lock
Acceptor提供prepare()方法:加互斥锁,给于var的互斥访问权,并返回var当前的取值f
Acceptor提供release()方法:释放互斥锁,收回var的互斥访问权
Acceptor提供accept()方法:如果已经加锁,并且var没有取值,则设置var为V,并且释放锁
<2>两阶段实现的propose(var,V):
第一阶段:通过Acceptor的prepare()方法获取互斥访问权和当前var的取值,如果不能获取,则返回(锁被别人占用)
第二阶段:根据当前的var的取值f,选择执行
如果f为null,则通过Acceptor的accept(var,V)提交数据V
如果f不为空,则通过Acceptor的release()方法释放访问权,返回(ok f)
<3>通过Acceptor互斥访问权让Proposer序列运行,可以简单实现var取值一致性
Proposer在释放互斥访问权之前发生故障,会导致系统陷入死锁
问题描述:Proposer不能发生故障
6.确定一个不可变变量的取值-方案2
<1>引入抢占式访问权
a.acceptor可以让某个proposer获取到的访问权失效,不再接收它的访问
b.之后,可以将访问权发放给其他的proposer,让其他proposer访问acceptor
<2>Proposer向Acceptor申请访问权时指定编号epoch(越大的epoch越新),获取到访问权之后,才能向acceptor提交取值
<3>Acceptor采用喜新厌旧的原则
a.一旦收到更大的新epoch的申请,马上让旧epoch的访问权失效,不再接收他们提交的取值
b.然后给新epoch发放访问权,只接收新epoch提交的取值
<4>新epoch可以抢占旧epoch,让旧epoch的访问权失效,旧epoch的proposer将无法运行,新epoch的propser将开始运行
<5>为了保持一致性,不同epoch的proposer之间采用”后者认同前者”的原则
a.在肯定旧epoch无法生成确定性取值时,新的epoch会提交自己的value.不会冲突
b.一旦旧epoch形成确定性取值,新的epoch肯定可以获取到此取值,并且会认同此取值,不会破坏.
<6>实现:
1)基于抢占式访问权的Acceptor的实现
Acceptor保存的状态
a.当前var的取值(accepted_epoch,accepted_value)
b.最新发放访问权的epoch(latested_prepared_epoch)
Acceptor的prepare(epoch)方法
a.只接收比latest_prepared_epoch更大的epoch,并给予访问权
b.记录latest_prepared_epoch=epoch,返回当前var的取值
Acceptor的accept(var,prepared_epoch,V)方法
a.验证 latest_prepared_epoch=prepared_epoch
b.设置var的取值(accepted_epoch,accepted_value)=(prepared_epoch,v)
2)Propose(var,V)的两阶段实现
第一阶段:获取epoch轮次的访问权和当前var的取值
a.简单选取当前时间戳为epoch,通过Acceptor的prepare(epoch),获取epoch轮次的访问权和当前var的取值
b.如果不能获取,说明有比当前epoch更大的epoch获取了访问权,则断掉当前的epoch,返回
第二阶段:采用”后者认同前者”的原则执行
a.在肯定旧epoch无法生成确定性取值时,新的epoch会提交自己的value,不会冲突
b.一旦旧epoch形成确定性取值,新的epoch肯定可以获取到此取值,并且会认同此取值,不会破坏
c.如果var的取值为空,则肯定旧epoch无法生成确定性取值,则通过Acceptor的accept(var,epoch,V)提交数据V.成功后返回(ok,V),如果accept失败,返回(error)
d.如果var取值存在,则此取值肯定是确定性取值,此时认同它不再更改,直接返回(ok,accepted_value)
<7>执行过程:
初始状态:
这里写图片描述
P1向Acceptor请求获取epoch1的访问权,因为当前acceptor没有接收到任何其他的epoch的访问权,接收p1,因此将latest_prepared_epoch的值设置为epoch1,并同时向p1返回取值(ok,null null)
这里写图片描述
P1完成第一阶段获取到了访问权,在P1进行第二阶段之前P2抢占到了epoch2的访问权,因为epoch2的访问权比epoch1要大,因此将epoch1的访问权失效,然后将epoch2的访问权生效,同时向P2返回Acceptor的取值null.P2的第一阶段完成
这里写图片描述
P2的第二阶段开始执行,提交P2自己的取值V2,Acceptor发现var当前的取值为null,因为将取值设置为(epoch2,v2),并将结果返回给P2.此时P1的第二阶段开始进行,向Acceptor提交自己的取值(epoch1,v1),因为当前的访问权已经被P2抢占,P1的请求失效,Acceptor不再接收P1的请求,P1失效
这里写图片描述
P3向Acceptor发起请求,想获取epoch3的访问权,因为当前Acceptor获取访问权的最大值epoch2,epoch3比epoch2大,因此Acceptor将epoch2失效,将latest_prepared_epoch设置成epoch3,此时因为Acceptor中的var已经设置为epoch2,v2,将该值直接返回给P3,P3对此值不再进行修改.
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值