Raft详解分析

1、投票部分

一个candidate向所有其他的server发送RequesetVote RPC(具体格式见论文),每次从RPC的reply中累加voteCount,如果超过一半,这个candidate变成leader,把这个消息放到channel中,反之选举失败,变成follower对应go 代码为:

if ok { //获取投票结果
if reply.VOTEGRANTED {
rf.mu.Lock()
rf.voteCount = rf.voteCount + 1
// println("rf.me: " + strconv.Itoa(rf.me) + " voteFrom: " + strconv.Itoa(server) + " voteCount: " + strconv.Itoa(rf.voteCount))
rf.mu.Unlock()
if rf.state == "candidate" && rf.voteCount > len(rf.peers)/2 {
rf.BecomeLeaderCH <- true
}
} else if reply.TERM > rf.CurrentTerm {
rf.mu.Lock()
rf.CurrentTerm = reply.TERM
rf.state = "follower"
rf.mu.Unlock()
// println(strconv.Itoa(server) + " reject " + strconv.Itoa(rf.me) + " and " + strconv.Itoa(rf.me) + " step down as follower")

如何处理放到channel中的选举结果呢?首先从channel中取出结果,如果是leader表示自己当选,修改自己状态为leader,把每个follower的nextIndex设置为当前leader的最后一个log的index(参见Raft论文),发送AppendEntries heartbeat 如果选举失败,则变成follower

func (rf *Raft) CandidateState() {
.......
select { 
case <-rf.heartbeatCH://已经有人当上leader,选举失败
println("no longer panic, back to follower")
rf.state = "follower"
return
case becomeLeader := <-rf.BecomeLeaderCH: //选举成功
if becomeLeader { 
rf.state = "leader"
rf.mu.Lock()
rf.NextIndex = []int{}
for i:=0; i < len(rf.peers); i++ {
rf.nextIndex = append(rf.nextIndex, len(rf.logs)-1) //把每个server 的nextIndex设置为最后一个元素
}
rf.mu.Unlock()
go rf.BroadcastAppendEntriesRPC()
return
}

default:
return  //多个竞争,大家都没有当上leader,则返回,在外部循环中重新设置各个candidate定时器,再次选举
}
}

时间: 2024-11-09 08:20:43

Raft详解分析的相关文章

MVC之前的那点事儿系列(3):HttpRuntime详解分析(下)(转载)

MVC之前的那点事儿系列(3):HttpRuntime详解分析(下) 文章内容 话说,经过各种各样复杂的我们不知道的内部处理,非托管代码正式开始调用ISPAIRuntime的ProcessRequest方法了(ISPAIRuntime继承了IISPAIRuntime接口,该接口可以和COM进行交互,并且暴露了ProcessRequest接口方法).至于为什么要调用这个方法,大叔也不太清楚,找不到微软相关的资料哦.但大叔确定该方法就是我们进入HttpRuntime的正式大门,接着看吧. publi

CentOS6启动过程超详解分析

CentOS 6 开机流程--linux由kernel和rootfs组成.kernel负责进程管理.内存管理.网络管理.驱动程序.文件系统.安全等;rootfs由程序和glibc组成,完善操作系统的功能.同时linux内核的特点是模块化,通过对模块装载卸载可以对内核功能自定义.linux内核文件:/boot/vmlinuz-2.6.32-696.el6.x86_64 整体的流程 BIOS/开机自检 MBR引导(Boot Loader) 启动内核 启动第一个进程init 一.BIOS/开机自检 1

lspci详解分析

lspci详解分析 一.PCI简介 PCI是一种外设总线规范.我们先来看一下什么是总线:总线是一种传输信号的路径或信道.典型情况是,总线是连接于一个或多个导体的电气连线,总 线上连接的所有设备可在同一时间收到所有的传输内容.总线由电气接口和编程接口组成.本文讨论Linux 下的设备驱动,所以,重点关注编程接口. PCI是Peripheral Component Interconnect(外围设备互联)的简称,是普遍使用在桌面及更大型的计算机上的外 设总线.PCI架构被设计为ISA标准的替代品,它

各大中间件底层技术-分布式一致性协议 Raft 详解

前言 正式介绍 Raft 协议之前,我们先来举个职场产研团队的一个例子??. 方式一: 在一个技术团队内假设角色都是 均等的,会导致什么情况呢?产品提出一个需求,就可以随便去找团队中的任意一个人去发起需求.如果这个人因为请假走了,但是他没有把需求及时同步给团队其他人,因此会导致该需求存在很大的延迟. 方式二: 在技术团队中选举一个 ** Leader角色**,产品提出的需求必须优先提给 Leader,找 Leader 先沟通.Leader 自己消化完后,在将需求传达给团队其他成员.如果 Lead

股票入门 教你如何详解分析K线

单根K线分析:什么是K线 1.K线的起源 K线的起源地是日本,属古老的技术分析方法.公元1750年,日本人就已经开始利用阴阳烛来分析大米期货,因此,K线又被称为日本线.随着时间的发展,K线才被慢慢应用到股票市场上.事实上,经过上百年的应用和变更,目前已形成了一套完整的股票K线分析理论. 2.K线的含义 在股市中,买方和卖方永远是站在对立的两边,K线就是将买卖双方实战结果,即买方和卖方力量的增减和转化过程用图形表示出来.由于K线表示买卖双方的实战结果,所以又可以称为阴阳线或红黑线,取阴阳相对.红黑

Javascript异步编程之setTimeout与setInterval详解分析(一)

Javascript异步编程之setTimeout与setInterval 在谈到异步编程时,本人最主要会从以下三个方面来总结异步编程( 注意: 特别解释:是总结,本人也是菜鸟,所以总结不好的,请各位大牛多多原谅!) 1. setTimeout与setInterval详细分析基本原理. 接下来这篇博客会总结setTimeout和setInterval基本点,对于上面三点会分三篇博客分别来总结,对于知道上面三点的人,但是又不是非常了解全面知识点的码农来说,没有关系的,我们可以慢慢来学习,来理解,或

Raft详解-启动后运行期间代码

Raft启动后运行期间主要执行两个函数:1.状态监测和转化 func (rf *Raft) Loop() { // Set out as a follower TimeOutConst := 0 for { TimeOutConst = ElectionTimeoutConst() if rf.state == "follower" { // DO FOLLOWER STUFF select { case <-rf.heartbeatCH: case <-time.Afte

MVC之前的那点事儿系列(3):HttpRuntime详解分析(下)

今天有幸被召回母校给即将毕业的学弟学妹们讲我这两年的工作史,看了下母校没啥特别的变化,就是寝室都安了空调,学妹们都非常漂亮而已..好了不扯蛋了,说下今天的主题吧.这些天我在深度定制语法高亮功能的同时发现了博客园提供的一些有意思的函数,甚至有几个博客园都没用到,我也不知道怎么才能触发那些功能..打开这个js就可以看到很多好用的东西了,虽然写的不怎么样,但是至少有这些功能. ps: 推荐安装一个代码格式化的插件,否则一坨看着蛋疼.比如第一个就是 log,方便调试. http://www.qidian

MVC之前的那点事儿系列(2):HttpRuntime详解分析(上)

position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位问题.所以当没有定义position属性时,并不说明该元素没有自己的位置,它会遵循默认显示为静态位置,在静态定位状态下无法通过坐标值(top,left,right,bottom)来改变它的位置. position:absolute(绝对定位) 当position属性定义为absolute时,元素会脱离文档流