Raft造轮子II
文章目录
【注意】最后更新于 April 13, 2018,文中内容可能已过时,请谨慎使用。
读过文章之后,我们虽然不知道具体的程序要怎么动笔,但是让我们说出来怎么选举领导人,怎么复制日志,对大家来说问题不大了。
怎么写第一步程序呢?我虽然看着pontoon的源码,但是依然有些无从下手的准备。 经过分析论文之后,感觉全文使用最多的就是通信的数据结构了。RequestVote RPC 和AppendEntries RPC 是通信的根本,而且,也定义了这两个函数的输入数据和输出数据,简直就只把代码给我们了呀!
前言
由于都是远程调用通信,我们可以直接使用rpc进行通信,protobuf作为数据格式,grpc进行通信即可。在此处不对rpc进行赘述,可以参考rpc学习或者官方网站进行学习。
AppendEntries
文章中说,附加日志远程调用,是由领导人进行复制日志和心跳包使用的,其中需要包含以下内容
1 2 3 4 5 6 |
Term 整数,表示领导人的任期 leaderId 整数,表示当前领导人的ID,这样其他客户端也可以给它发送消息 prevLogIndex 整数,最新日志的上一条日志序号 prevLogTerm 整数,prevLogIndex的领导人的Term值 entries[] 数组,各个节点要存储的日志内容 leaderCommit 整数,提交日志的序号 |
为什么要用两个prevLog呢?论文中也说到了,是为了检查日志连续性的,我们以后的代码会涉及到对这两点的检验。 客户端收到leader发来的请求后,需要回复给leader,回复的内容如下
1 2 |
term 整数,当前的任期号 success 布尔,如果数据通过,就返回true |
理解了这些,我们就可以放心的定义数据结构了
|
|
对于这个的操作服务也是很简单
|
|
RequestVote
除了提供这个服务,还有一个RequestVote服务,请求方需要提供这些数据内容
1 2 3 4 |
Term 整数,候选人的任期号 CandidateId 字符串,候选人的Id lastLogIndex 整数,候选人最新的日志序号 lastLogTerm 整数,候选人最新日志的任期号 |
数据返回内容一样很简单
1 2 |
Term 整数,目前的任期号,候选人可以进行更新 VoteGranted 布尔,是否给候选人投票 |
转换成代码就是这样
|
|
rpc调用也很简单
|
|
写好后,我们就可以编译生成go文件了。 文件内容参见message.proto
编译
由于我使用的是window系统,在运行的时候很容易找不到对应的库文件,我们需要进行指定,我的命令是这样的
|
|
大家可以参考下。
结束
这块的内容还是比较简单的,因为论文几乎给了我们直接的数据结构,我们所需做的就是写成代码而已。我们会继续进行后续的文章。