分布式一致性算法Paxos JAVA多线程方式实现

来源:互联网 发布:mac系统还原到旧版本 编辑:程序博客网 时间:2024/06/10 07:44
github地址:

https://github.com/hellolinjx/PaxosImpl/


//准备提案过程,获得大多数决策者支持后进入确认提案阶段。public synchronized boolean prepare(){PrepareResult prepareResult = null;boolean isContinue = true;//已获得承诺个数int promisedCount = 0;do{List<Proposal> promisedProposals = new ArrayList<Proposal>(); List<Proposal> acceptedProposals = new ArrayList<Proposal>();promisedCount = 0;for(Acceptor acceptor : acceptors){prepareResult = acceptor.onPrepare(proposal);//随机休眠一段时间,模拟网络延迟。PaxosUtil.sleepRandom();//模拟网络异常if(null==prepareResult){continue;}//获得承诺if(prepareResult.isPromised()){promisedCount ++;}else{//决策者已经给了更高id题案的承诺if(prepareResult.getAcceptorStatus()==AcceptorStatus.PROMISED){promisedProposals.add(prepareResult.getProposal());}//决策者已经通过了一个题案if(prepareResult.getAcceptorStatus()==AcceptorStatus.ACCEPTED){acceptedProposals.add(prepareResult.getProposal());}}}// end of for//获得多数决策者的承诺//可以进行第二阶段:题案提交if(promisedCount >= halfCount){break;}Proposal votedProposal = votedEnd(acceptedProposals);//决策者已经半数通过题案if(votedProposal !=null){System.out.println("决策已经投票结束:" + votedProposal);return true;}Proposal maxIdAcceptedProposal = getMaxIdProposal(acceptedProposals);//在已经被决策者通过题案中选择序列号最大的决策,作为自己的决策。if(maxIdAcceptedProposal != null){proposal.setId(PaxosUtil.generateId());proposal.setValue(maxIdAcceptedProposal.getValue());}else{proposal.setId(PaxosUtil.generateId());}}while(isContinue);return false;}//获得大多数决策者承诺后,开始进行提案确认public synchronized boolean commit(){ boolean isContinue = true;//已获得接受该提案的决策者个数int acceptedCount = 0;do{List<Proposal> acceptedProposals = new ArrayList<Proposal>();acceptedCount = 0;for(Acceptor acceptor : acceptors){CommitResult commitResult = acceptor.onCommit(proposal);//模拟网络延迟PaxosUtil.sleepRandom();//模拟网络异常if(null==commitResult){continue;}//题案被决策者接受。if(commitResult.isAccepted()){acceptedCount ++;}else{acceptedProposals.add(commitResult.getProposal());}}//题案被半数以上决策者接受,说明题案已经被选出来。if(acceptedCount >= halfCount){System.out.println("题案已经投票选出:" + proposal);return true;}else{Proposal maxIdAcceptedProposal = getMaxIdProposal(acceptedProposals);//在已经被决策者通过题案中选择序列号最大的决策,重新生成递增id,改变自己的value为序列号最大的value。//这是一种预测,预测此maxIdAccecptedProposal最有可能被超过半数的决策者接受。if(maxIdAcceptedProposal != null){proposal.setId(PaxosUtil.generateId());proposal.setValue(maxIdAcceptedProposal.getValue());}else{proposal.setId(PaxosUtil.generateId());}//回退到决策准备阶段if(prepare())return true;}}while(isContinue);return true;}

//加锁此准备函数,不允许同时访问。模拟单个决策者串行处理一个请求。public synchronized PrepareResult onPrepare(Proposal szProposal){PrepareResult prepareResult = new PrepareResult();//模拟网络不正常,发生丢包、超时现象if(PaxosUtil.isCrashed()){PaxosUtil.printStr("Network not normal: " + this.toString());return null;}switch (status){//NONE表示之前没有承诺过任何提议者//此时,接受提案case NONE:prepareResult.setAcceptorStatus(AcceptorStatus.NONE);prepareResult.setPromised(true);prepareResult.setProposal(null);//转换自身的状态,已经承诺了提议者,并记录承诺的提案。status = AcceptorStatus.PROMISED;promisedProposal.copyFromInstance(szProposal);return prepareResult;//已经承诺过任意提议者case PROMISED://判断提案的先后顺序,只承诺相对较新的提案if(promisedProposal.getId() > szProposal.getId()){prepareResult.setAcceptorStatus(status);prepareResult.setPromised(false);prepareResult.setProposal(promisedProposal);return prepareResult;}else{promisedProposal.copyFromInstance(szProposal);prepareResult.setAcceptorStatus(status);prepareResult.setPromised(true);prepareResult.setProposal(promisedProposal);return prepareResult;}//已经批准过提案case ACCEPTED://如果是同一个提案,只是序列号增大//批准提案,更新序列号。if(promisedProposal.getId()<szProposal.getId()&& promisedProposal.getValue().equals(szProposal.getValue())){promisedProposal.setId(szProposal.getId());prepareResult.setAcceptorStatus(status);prepareResult.setPromised(true);prepareResult.setProposal(promisedProposal);return prepareResult;}else{ //否则,不予批准prepareResult.setAcceptorStatus(status);prepareResult.setPromised(false);prepareResult.setProposal(acceptedProposal);return prepareResult;}default://return null;}return null;}//加锁此提交函数,不允许同时访问,模拟单个决策者串行决策public synchronized CommitResult onCommit(Proposal szProposal){CommitResult commitResult = new CommitResult();if(PaxosUtil.isCrashed()){return null;}switch (status){//不可能存在此状态case NONE:return null;//已经承诺过提案case PROMISED://判断commit提案和承诺提案的序列号大小//大于,接受提案。if(szProposal.getId() >= promisedProposal.getId()){promisedProposal.copyFromInstance(szProposal);acceptedProposal.copyFromInstance(szProposal);status = AcceptorStatus.ACCEPTED;commitResult.setAccepted(true);commitResult.setAcceptorStatus(status);commitResult.setProposal(promisedProposal);return commitResult;}else{//小于,回绝提案commitResult.setAccepted(false);commitResult.setAcceptorStatus(status);commitResult.setProposal(promisedProposal);return commitResult;}//已接受过提案case ACCEPTED://同一提案,序列号较大,接受if(szProposal.getId() > acceptedProposal.getId()&& szProposal.getValue().equals(acceptedProposal.getValue())){acceptedProposal.setId(szProposal.getId());commitResult.setAccepted(true);commitResult.setAcceptorStatus(status);commitResult.setProposal(acceptedProposal);return commitResult;}else{//否则,回绝提案commitResult.setAccepted(false);commitResult.setAcceptorStatus(status);commitResult.setProposal(acceptedProposal);return commitResult;}}return null;}


原创粉丝点击