Skip to content

Commit 78b0115

Browse files
author
成旭
committed
add file
1 parent f5e8bd5 commit 78b0115

File tree

6 files changed

+38
-2
lines changed

6 files changed

+38
-2
lines changed

img/appent_rpc.png

376 KB
Loading

img/rpc_vote.png

253 KB
Loading

img/rule.png

545 KB
Loading

img/state.png

383 KB
Loading

src/raft/raft-impl.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# 分布式一致性协议 raft 一步一步的去实现
2+
3+
4+
随着大型网站的各种高并发访问、海量数据处理等场景越来越多,如何实现网站的高可用、易伸缩、可扩展、安全等目标就显得越来越重要。
5+
为了解决这样一系列问题,大型网站的架构也在不断发展。提高大型网站的高可用架构,不得不提的就是分布式。
6+
任何一个分布式系统都无法同时满足Consistency(一致性),Availability(可用性), Partition tolerance(分区容错性) 这三个基本需求。
7+
最多只能满足其中两项。 但是,一个分布式系统无论在CAP三者之间如何权衡,都无法彻底放弃一致性(Consistency),如果真的放弃一致性,
8+
那么就说明这个系统中的数据根本不可信,数据也就没有意义,那么这个系统也就没有任何价值可言。所以,无论如何,分布式系统的一致性问题都需要重点关注。
9+
10+
raft 适用于一个管理日志一致性的协议,相比于Paxos协议raft更易于理解和去实现它
11+
12+
# part1
13+
14+
Raft 通过选举一个领导人,然后给予他全部的管理复制日志的责任来实现一致性。领导人从客户端接收日志条目,把日志条目复制到其他服务器上,
15+
并且当保证安全性的时候告诉其他的服务器应用日志条目到他们的状态机中。拥有一个领导人大大简化了对复制日志的管理。例如,领导人可以决定新的日志条目需要放在日志中的什么位置而不需要和其他服务器商议,
16+
并且数据都从领导人流向其他服务器。一个领导人可以宕机,可以和其他服务器失去连接,这时一个新的领导人会被选举出来。
17+
18+
Raft 把时间分割成任意长度的任期,任期用连续的整数标记。每一段任期从一次选举开始,一个或者多个候选人尝试成为领导者。如果一个候选人赢得选举,然后他就在接下来的任期内充当领导人的职责。
19+
在某些情况下,一次选举过程会造成选票的瓜分。在这种情况下,这一任期会以没有领导人结束;一个新的任期(和一次新的选举)会很快重新开始。Raft 保证了在一个给定的任期内,最多只有一个领导者。
20+
21+
要实现raft 协议,参见如下图
22+
23+
![状态机持有的变量](img/state.png)
24+
25+
![投票请求](img/rpc_vote.png)
26+
27+
![日志发送](img/appent_rpc.png)
28+
29+
![服务器的应用规则](img/rule.png)
30+
31+
32+
33+
34+

src/raft/raft.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ func (rf *Raft) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) {
213213
reply.VoteGranted = false
214214
if args.Term < rf.currentTerm {
215215
reply.Term = rf.currentTerm
216-
//fmt.Printf("%v currentTerm:%v vote reject for:%v term:%v",rf.me,rf.currentTerm,args.CandidateId,args.Term)
217216
return
218217
}
219218
//If RPC request or response contains term T > currentTerm: set currentTerm = T, convert to follower
@@ -559,19 +558,22 @@ func (rf *Raft) broadcastRequestVote() {
559558
if i != rf.me && rf.state == CANDIDATE {
560559
go func(i int) {
561560
var reply RequestVoteReply
562-
//fmt.Printf("%v RequestVote to %v\n",rf.me,i)
563561
rf.sendRequestVote(i, args, &reply)
564562
}(i)
565563
}
566564
}
567565
}
568566

567+
/**
568+
* Log replication
569+
*/
569570
func (rf *Raft) broadcastAppendEntries() {
570571
rf.mu.Lock()
571572
defer rf.mu.Unlock()
572573
N := rf.commitIndex
573574
last := rf.getLastIndex()
574575
baseIndex := rf.log[0].LogIndex
576+
//If there exists an N such that N > commitIndex, a majority of matchIndex[i] ≥ N, and log[N].term == currentTerm: set commitIndex = N
575577
for i := rf.commitIndex + 1; i <= last; i++ {
576578
num := 1
577579
for j := range rf.peers {

0 commit comments

Comments
 (0)