mit6.824学习笔记及学习路线(持续更新 | 论文思想抽象总结)

本人现在在美本CS,由于疫情在家上网课,研究一下分布式。目前youtube看视频、读论文、做lab。顺便每天晚上更新今天新增的知识,欢迎交流。

网上mit6.824的教程已经很多了,大多数是把一个正确代码分段加注释,弄清楚一段代码的作用和原理。这样固然没错,但是任何一个算法或者协议,都有不同场景下的实现,更加重要的是把握算法背后的思想。

Raft 算法

这个目前跟着mit的lab在做。前段时间产生了一个误区,认为Raft里的log就是用户的请求。实际不是,raft内部的log只是维护一致性和选举所交换的信息

需要理解的Raft

个人感觉和经验,写完这个算法,重点是要理解go语言的特性,以及项目想传递的思想,test过没过,并不重要,那我来记录一下思想方面的问题。

1.  paper方面一定要读懂的,非常精华,特别是section2的figure

2. 类似于CS537的scheduler。如果要我说一句话总结raft,那就是:raft是一群节点、三个状态,一直循环各司其职。这就是raft的核心。工业界并不关心具体的log,重点是如何election以及timeout (下图我们在后文详细讲解)

func (rf *Raft) runServer() {
	for {
		switch rf.status {
		case Leader:
                    AppendEntry()
		case Follower:
                // 1. Check HeartBeat
                // 2. Check if itself has voted
                // 3. After timeout, become a Condidate
		case Candidate:
			// 1. Ask other people to vote
		}
	}
}

 Go在这里的特性(我觉得这里是对于Go初学者的重点,好好讲一下)

  • 关于分布式,Goroutine。我们在election的时候并不用单线程来发送request,而是发完,不等待peer回复,直接回到2中提到的while loop。
  • (接上)这里就是channel的作用了,我们定义好一个electwin chan bool, 当我们发现被选成leader了,或者有人已经成为leader了,我们可以用channel进行通信。这里用的go语法是select
  • RPC。那么不同的peers之间就是叫RPC了,RPC无非是一个request和response的模型,在cs640中是REQ和ACK,其实都可以叫RPC。只不过在go中有特定的语法
    func (rf *Raft) sendAppendEntries(server int, args *AppendEntriesArgs, reply *AppendEntriesReply) bool {
    	ok := rf.peers[server].Call("Raft.AppendEntries", args, reply)
    }

    用到goroutine的地方

  • commit log的时候,我们并不需要等待一个个commit结束。(原因是我们使用了channel,可能因为client的处理而阻塞)
  • 群发requestVote和appendEntry的时候,一个个发过去,然后回到主while loop中等channel给信号即可(electwin,heartbeat等chan)

 

说一下follower、candidate、leader都在干嘛

先描述,后贴代码。

leader:sendAppendEntries

leader只做一件事:协调followers

接受client给的log,不停的给followers发pkt,会根据RPC reply的内容更改自己的策略。因此leader的RPC其实是一个双向交互。

有两个点我觉得设计的很巧妙

// Volatile state on leaders:
	nextIndex [] int
	matchIndex [] int

由于log可能会产生许多的错误,比如少了,多了,冲突了。那么我们记录对每一个peer一个nextIndex,这样子可以把nextIndex之后的log一次性覆盖成leader的样子。

有一个小Trick:当我们发现冲突的时候,直接认为当前term的log我都不要了,以免一个个log都用prevIndex & prevTerm check,从而reduce the # of RPC

 

Candidate: sendRequestVote

Candidate做了三件事

1. 请求别人给自己投票(默认FIFO),但是根据业务可以有多种变型。这就是我开头为什么说记代码没用。lecture中提到了:选取log最多的优先,选取term最大的优先,etc.

2. 发现有人成为了leader(即收到了heartbeat via channel),放弃竞选成为follower

3. 选举成功(通过elecwin),转变为follower

 

Follower:handle two kind of request

没错follower在这里的主要功能就是更新自己的log以及投票,就是在解决上述的两种RPC。

如果一段时间没有heartbeat或者也没有给别人投票,那就自己变成candidate

 

Etcd

感觉是替代zookeeper的轻量级算法?并没有完全搞懂zookeeper

1. 一个优化就是使读操作可以不必须经过leader,从而实现了:“增加服务器同时也是增加performance”的目的

2. 其余的先留个坑

 

由etcd引申出来的知识

1. https://www.jianshu.com/p/66e2a0cd93d5

2. 微服务

3. zookeeper论文还是读一下

4. lab继续做

 

 

 

 

 

你可能感兴趣的:(分布式)