raft算法练习-模拟三节点的分布式选举

本文深入探讨了Raft一致性算法的实现细节,包括Leader选举、日志复制等关键流程,并通过Go语言示例代码展示了如何在分布式系统中实现这些功能。

raft理论知识(网络上有很多,所以理论不是这篇文章的核心)

Raft是一个用于管理日志一致性的协议。它将分布式一致性分解为多个子问题:Leader选举(Leader election)、日志复制(Log replication)、安全性(Safety)、日志压缩(Log compaction)等。同时,Raft算法使用了更强的假设来减少了需要考虑的状态,使之变的易于理解和实现。Raft将系统中的角色分为领导者(Leader)、跟从者(Follower)和候选者(Candidate):

Leader:接受客户端请求,并向Follower同步请求日志,当日志同步到大多数节点上后告诉Follower提交日志。

Follower:接受并持久化Leader同步的日志,在Leader告之日志可以提交之后,提交日志。

Candidate:Leader选举过程中的临时角色。

Raft要求系统在任意时刻最多只有一个Leader,正常工作期间只有Leader和Followers。Raft算法将时间分为一个个的任期(term),每一个term的开始都是Leader选举。在成功选举Leader之后,Leader会在整个term内管理整个集群。如果Leader选举失败,该term就会因为没有Leader而结束。

Leader选举的过程
  Raft 使用心跳(heartbeat)触发Leader选举。当服务器启动时,初始化为Follower。Leader向所有Followers周期性发送heartbeat。如果Follower在选举超时时间内没有收到Leader的heartbeat,就会等待一段随机的时间后发起一次Leader选举。

每一个follower都有一个时钟,是一个随机的值,表示的是follower等待成为leader的时间,谁的时钟先跑完,则发起leader选举。

Follower将其当前term加一然后转换为Candidate。它首先给自己投票并且给集群中的其他服务器发送 RequestVote RPC。结果有以下三种情况:

赢得了多数的选票,成功选举为Leader;

收到了Leader的消息,表示有其它服务器已经抢先当选了Leader;

没有服务器赢得多数的选票,Leader选举失败,等待选举时间超时后发起下一次选举。

实现(本文核心)

package main

import (
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"net/rpc"
	"sync"
	"time"
)

//模拟三节点的分布式选举


//定义常量3
const raftCount = 3



//声明leader对象
type Leader struct {
   
   
	//任期
	Term int
	//领导编号
	LeaderId int
}


//创建存储leader的对象
//最初任期为0,-1代表没编号
var leader = Leader{
   
   0, -1}


//声明raft节点类型
type Raft struct {
   
   
	//锁
	mu sync.Mutex
	//节点编号
	me int
	//当前任期
	currentTerm int
	//为哪个节点投票
	votedFor int
	//当前节点状态
	//0 follower  1 candidate  2 leader
	state int
	//发送最后一条消息的时间
	lastMessageTime int64
	//当前节点的领导
	currentLeader int

	//消息通道
	message chan bool
	//选举通道
	electCh chan bool
	//心跳信号
	heartBeat chan bool
	//返回心跳信号
	hearbeatRe chan bool
	//超时时间
	timeout int
}


func main() {
   
   
	//过程:创建三个节点,最初是follower状态
	//如果出现candidate状态的节点,则开始投票
	//产生leader

	//创建三个节点
	for i := 0; i < raftCount; i++ {
   
   
		//定义Make() 创建节点
		Make(i)
	}

	//对raft结构体实现rpc注册
	rpc.Register(new(Raft))
	rpc.HandleHTTP()
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
   
   
		log.Fatal(err)
	}

	//防止选举没完成,main结束了
	for {
   
   ;
	}
}



//创建节点
func Make(me int) *Raft {
   
   
	rf := &Raft{
   
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值