Skip to content

Commit

Permalink
add file
Browse files Browse the repository at this point in the history
  • Loading branch information
成旭 committed Jan 31, 2017
1 parent f5e8bd5 commit 78b0115
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 2 deletions.
Binary file added img/appent_rpc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/rpc_vote.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/rule.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/state.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions src/raft/raft-impl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 分布式一致性协议 raft 一步一步的去实现


随着大型网站的各种高并发访问、海量数据处理等场景越来越多,如何实现网站的高可用、易伸缩、可扩展、安全等目标就显得越来越重要。
为了解决这样一系列问题,大型网站的架构也在不断发展。提高大型网站的高可用架构,不得不提的就是分布式。
任何一个分布式系统都无法同时满足Consistency(一致性),Availability(可用性), Partition tolerance(分区容错性) 这三个基本需求。
最多只能满足其中两项。 但是,一个分布式系统无论在CAP三者之间如何权衡,都无法彻底放弃一致性(Consistency),如果真的放弃一致性,
那么就说明这个系统中的数据根本不可信,数据也就没有意义,那么这个系统也就没有任何价值可言。所以,无论如何,分布式系统的一致性问题都需要重点关注。

raft 适用于一个管理日志一致性的协议,相比于Paxos协议raft更易于理解和去实现它

# part1

Raft 通过选举一个领导人,然后给予他全部的管理复制日志的责任来实现一致性。领导人从客户端接收日志条目,把日志条目复制到其他服务器上,
并且当保证安全性的时候告诉其他的服务器应用日志条目到他们的状态机中。拥有一个领导人大大简化了对复制日志的管理。例如,领导人可以决定新的日志条目需要放在日志中的什么位置而不需要和其他服务器商议,
并且数据都从领导人流向其他服务器。一个领导人可以宕机,可以和其他服务器失去连接,这时一个新的领导人会被选举出来。

Raft 把时间分割成任意长度的任期,任期用连续的整数标记。每一段任期从一次选举开始,一个或者多个候选人尝试成为领导者。如果一个候选人赢得选举,然后他就在接下来的任期内充当领导人的职责。
在某些情况下,一次选举过程会造成选票的瓜分。在这种情况下,这一任期会以没有领导人结束;一个新的任期(和一次新的选举)会很快重新开始。Raft 保证了在一个给定的任期内,最多只有一个领导者。

要实现raft 协议,参见如下图

![状态机持有的变量](img/state.png)

![投票请求](img/rpc_vote.png)

![日志发送](img/appent_rpc.png)

![服务器的应用规则](img/rule.png)





6 changes: 4 additions & 2 deletions src/raft/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ func (rf *Raft) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) {
reply.VoteGranted = false
if args.Term < rf.currentTerm {
reply.Term = rf.currentTerm
//fmt.Printf("%v currentTerm:%v vote reject for:%v term:%v",rf.me,rf.currentTerm,args.CandidateId,args.Term)
return
}
//If RPC request or response contains term T > currentTerm: set currentTerm = T, convert to follower
Expand Down Expand Up @@ -559,19 +558,22 @@ func (rf *Raft) broadcastRequestVote() {
if i != rf.me && rf.state == CANDIDATE {
go func(i int) {
var reply RequestVoteReply
//fmt.Printf("%v RequestVote to %v\n",rf.me,i)
rf.sendRequestVote(i, args, &reply)
}(i)
}
}
}

/**
* Log replication
*/
func (rf *Raft) broadcastAppendEntries() {
rf.mu.Lock()
defer rf.mu.Unlock()
N := rf.commitIndex
last := rf.getLastIndex()
baseIndex := rf.log[0].LogIndex
//If there exists an N such that N > commitIndex, a majority of matchIndex[i] ≥ N, and log[N].term == currentTerm: set commitIndex = N
for i := rf.commitIndex + 1; i <= last; i++ {
num := 1
for j := range rf.peers {
Expand Down

0 comments on commit 78b0115

Please sign in to comment.