Raft

package
v0.0.0-...-e11b555 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2020 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	Follower = iota
	Candidate
	Leader
)

raft的三种角色

Variables

This section is empty.

Functions

This section is empty.

Types

type AppendEntriesArgs

type AppendEntriesArgs struct {
	Term         int        // leader的任期号
	LeaderID     uint64     // leaderID 便于进行重定向
	PrevLogIndex int        // 新日志之前日志的索引值
	PrevLogTerm  int        // 新日志之前日志的Term
	Entries      []LogEntry // 存储的日志条目 为空时是心跳包
	LeaderCommit int        // leader已经提交的日志的索引
}

同步日志,日志项为空时可当做心跳包

type AppendEntriesReply

type AppendEntriesReply struct {
	CurrentTerm int  // 用于更新leader本身 因为leader可能会出现分区
	Success     bool // follower如果跟上了PrevLogIndex,PrevLogTerm的话为true,否则的话需要与leader同步日志

	// 用于同步日志
	ConflictTerm int // term of the conflicting entry
	FirstIndex   int // the first index it stores for ConflictTerm

	IsOk bool
}

type ApplyMsg

type ApplyMsg struct {
	Index       int
	Command     interface{}
	UseSnapshot bool   // true为快照;false为一般command
	Snapshot    []byte // 快照数据

}

type InstallSnapshotArgs

type InstallSnapshotArgs struct {
	Term              int    // 领导人的任期号
	LeaderID          uint64 // 领导人的ID,以便于跟随者重定向请求
	LastIncludedIndex int    // 快照中包含的最后日志条目的索引值
	LastIncludedTerm  int    // 快照中包含的最后日志条目的任期号
	Snapshot          []byte // 快照数据
}

type InstallSnapshotReply

type InstallSnapshotReply struct {
	CurrentTerm int // leader可能已经落后了,用于更新leader

	IsOk bool
}

type LogEntry

type LogEntry struct {
	Term    int
	Command interface{}
}

日志项

type Raft

type Raft struct {
	CurrentTerm int        // 服务器最后一次知道的任期号(初始化为 0,持续递增)
	VotedFor    uint64     // 在当前获得选票的候选人的 Id
	Logs        []LogEntry // 日志条目集;每一个条目包含一个用户状态机执行的指令,和收到时的任期号

	ConnectIsok *int32 // 参考RaftKV中的解释
	// contains filtered or unexported fields
}

func MakeRaftInit

func MakeRaftInit(me uint64,
	persister *Persister.Persister, applyCh chan ApplyMsg, IsOk *int32, address *[]string) *Raft

* @brief: 用于创建一个raft实体

func (*Raft) AppendEntries

func (rf *Raft) AppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply) error

AppendEntries定义了follower节点收到appendentries以后的处理逻辑

  • 其实一共四种情况,就是follower日志多于leader,follower日志少于leader,follower日志等于leader(最新index处Term是否相同)

func (*Raft) CreateSnapshots

func (rf *Raft) CreateSnapshots(index int)

* @brief: 用于在日志超过阈值时进行日志压缩,由kv层调用,index之前已经生成快照了 * @notes: 由raft的锁保护,不需要放在kvraft的临界区内

func (*Raft) GetState

func (rf *Raft) GetState() (int, bool)

得到自己的状态,并返回自己是不是leader

func (*Raft) InstallSnapshot

func (rf *Raft) InstallSnapshot(args *InstallSnapshotArgs, reply *InstallSnapshotReply) error

func (*Raft) MakeRaftServer

func (rf *Raft) MakeRaftServer(peers []*rpc.Client)

func (*Raft) RequestVote

func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) error

RequestVote定义了Follower收到投票以后的处理逻辑

  • 我们在这个函数中需要实现将请求者的日志和被请求者的日志作对比 如果当前节点的Term比候选者节点的Term大,拒绝投票
  • 1.如果当前节点的Term比候选者节点的Term大,拒绝投票
  • 2.如果当前节点的Term比候选者节点的Term小,那么当前节点转换为Follwer状态
  • 3.判断是否已经投过票
  • 4.比较最后一项日志的Term,也就是LastLogTerm,相同的话比较索引,也就是LastLogIndex,如果当前节点较新的话就不会投票,否则投票

func (*Raft) Start

func (rf *Raft) Start(command interface{}) (int, int, bool)

* @brief: raft的入口 * @params: 传入一个命令实体 * @ret: 返回这条命令在日志中的index,term和此节点在执行命令时是否为leader

type RequestVoteArgs

type RequestVoteArgs struct {
	Term         int    // 候选人的任期号 2A
	CandidateID  uint64 // 请求选票的候选人ID 2A
	LastLogIndex int    // 候选人的最后日志条目的索引值 2A
	LastLogTerm  int    // 候选人的最后日志条目的任期号 2A
}

type RequestVoteReply

type RequestVoteReply struct {
	CurrentTerm int  // 当前任期号,便于返回后更新自己的任期号 2A
	VoteGranted bool // 候选人赢得了此张选票时为真 2A

	IsOk bool // 用于告诉请求方对端的服务器是否已经启动
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL