Raft实现思路+细节

2A

任务分解

总体来说,2A中主要的任务就是选出领导人,在选出领导人的时候,我们要遵循下图。

在2A中,由于并没有出现日志复制,所以我们只需要考察两者的任期是否相等,以及接收者在本轮任期中有没有投票即可。

因而我们可以这样地给出2A中的实现内容:

  • 完善GetState()函数,这样才能让评测机知道我们选出了Leader

  • 完善Raft结构体(见论文上的State)

  • 完善RequestVote()函数,按照上图中的逻辑

  • 完善Make()函数,对成员进行初始化

  • 完善ticker()MakeElection()函数,在没有收到领导人信息的时候开始选举

  • 初步写出heartbeat相关功能(只需要在接收时变成跟随者即可)

实现细节

  1. 关于Raft结构体,基本上需要参考论文上的State即可。

    我在这里多加了一个safe状态(表示作为跟随者在这个周期内有没有收到领导人的信息,在收到RPC时置为true,在ticker()初始化和变成跟随者时变成false,若ticker()检查时为false,则直接开始选举),这样就模拟了发动选举的过程。(credit to @Vargvain )

  2. 关于RequestVote()函数,在2A阶段我们先判断任期的大小关系,如果候选人更大,那就让接收者先同步任期,并变成追随者;如果接收者更大,就直接返回false。如果相等,那么就看是否已经投过票,如果投过,返回false,反之返回true

    在这里,我建议封装好toCandidate(), toFollower(), toLeader()这几个函数,这样可以减少代码复用,而且用到的也确实挺多的

  3. 关于Make()函数,我们暂时只要给不同变量赋上初始值。

  4. 关于ticker()函数。首先要做的是调整ElectionTimeout,论文中有提到heartbeatInterval << ElectionTimeout,并且通过分析可以发现ElectionTimeout中随机值上界不超过下界的两倍,我选择ElectionTimeout = 400 + (rand.Int63() % 400)。接下来就是看是否是一个not safe的跟随者,如果是这样,那就开始选举(一个Go程)。

    选举函数基本是2A中最大的难点。首先,我们需要给RequestVoteArgs赋好初始值,然后就对于每一个peer(当然,peerId != rf.me),处理RequestVoteReply,如果回复的任期更高,那就变成Follower,反之,统计票数,如果超过半数,就变成领导人。

  5. 关于heartbeat,只需要依照RequestVoteRPC的格式完成基本的AppendEntriesRPC,并在变成领导人时给每个人发就行。

注意事项

关于锁的一些小建议(credit to @lauyeeyu)

  • 尽量缩短 Lock() 和 Unlock() 之间的长度(更细的控制)
  • 在Sleep或者耗时间的操作中不要持有锁,会占用进程,或导致死锁
  • 小心控制流语句 (continue, break, return) 可能会跳过你写的 Unlock()
  • 读写变量前别忘了上锁
  • 必要时(为了缩短上锁区域的长度)可以变量先读到临时变量,然后就可以解锁了,之后读取可以使用临时变量(但是要小心数据修改可能的隐患)

关于并发

  • 有必要再去了解一下并发进行的形式和原理

​ 对于这种情况,如果里面不用_peerId会出问题,因为在新开的Go程进行到某一阶段时可能peerId已经发生了变化。

关于测试

总时长情况大概如下图:

关于每一个测试后面的四个数字意义,见MIT课程页面

MIT 6.5840 Raft Implementation(2A, Leader Election)的更多相关文章

  1. ZooKeeper leader election

    Paxos是分布式应用中解决同步问题的核心.作为应用研发工程师,我们总是倾向于使用一种相对简洁的方式实现复杂的算法.ZooKeeper leader election实现就是一个非常好的参考. 其实现 ...

  2. Kafka配置项unclean.leader.election.enable造成consumer出现offset重置现象

    消费端出现offset重置为latest, earliest现象,类似log: (org.apache.kafka.clients.consumer.internals.Fetcher.handleF ...

  3. Leader Election 选举算法

    今天讲一讲分布式系统中必不可少的选举算法. leader 就是一堆服务器中的协调者,某一个时刻只能有一个leader且所有服务器都承认这个leader. leader election就是在一组进程中 ...

  4. Leader Election

    Leader Election Zookeeper的基本操作 Zookeeper虽然是分布式系统,但它并不是为文件存储而设计的,Zookeeper里存储的一般是配置信息和源信息.实际上,Zookeep ...

  5. Kafka学习笔记(4)----Kafka的Leader Election

    1. Zookeeper的基本操作 zookeeper中的节点可以持久化/有序的两个维度分为四种类型: PERSIST:持久化无序(保存在磁盘中) PERSIST_SEQUENTIAL:持久化有序递增 ...

  6. Zookeeper 学习笔记之 Leader Election

    ZooKeeper四种节点类型: Persist Persist_Sequential Ephemeral Ephemeral_Sequential 在节点上可注册的Watch,客户端先得到通知再得到 ...

  7. MIT 6.824 Lab2A Raft之领导者选举

    实验准备 实验代码:git://g.csail.mit.edu/6.824-golabs-2021/src/raft 如何测试:go test -run 2A -race 相关论文:Raft Exte ...

  8. Raft

    http://thesecretlivesofdata.com/raft/ https://github.com/coreos/etcd   1 Introduction Consensus algo ...

  9. Raft翻译

    英文原文:https://web.stanford.edu/~ouster/cgi-bin/papers/raft-atc14 In Search of an Understandable Conse ...

  10. Raft与MongoDB复制集协议比较

    在一文搞懂raft算法一文中,从raft论文出发,详细介绍了raft的工作流程以及对特殊情况的处理.但算法.协议这种偏抽象的东西,仅仅看论文还是比较难以掌握的,需要看看在工业界的具体实现.本文关注Mo ...

随机推荐

  1. 【Vue2.x源码系列06】计算属性computed原理

    上一章 Vue2异步更新和nextTick原理,我们介绍了 JavaScript 执行机制是什么?nextTick源码是如何实现的?以及Vue是如何异步更新渲染的? 本章目标 计算属性是如何实现的? ...

  2. 天梯赛L1-027 出租

    一.问题描述 下面是新浪微博上曾经很火的一张图: 一时间网上一片求救声,急问这个怎么破.其实这段代码很简单,index数组就是arr数组的下标,index[0]=2 对应 arr[2]=1,index ...

  3. 3.2 构造器、this、包机制、访问修饰符、封装

    构造器 构造器:在实例化的一个对象的时候会给对象赋予初始值,因此我们可以通过修改构造器,来改变对象的初始值,构造器是完成对象的初始化,并不是创建对象 我们也可以创建多个构造器实现不同的初始化,即构造器 ...

  4. 互异关系容斥&集合幂级数小记

    最近碰见了一些互异关系容斥的题目,而这类题目往往要配合集合幂级数的一些技术使用,所以简单记记. 内容很杂,行文很乱,作者水平很低,酌情观看. 互异关系容斥 思想其实很基本,应用范围其实很广. 原论文. ...

  5. 2022-04-28:有 n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,

    2022-04-28:有 n 个城市通过一些航班连接.给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始, ...

  6. Django4全栈进阶之路1 Django4下载与安装

    python 下载安装: 下载网址:https://www.python.org/downloads/ 安装方法:https://www.cnblogs.com/beichengshiqiao/p/1 ...

  7. CF1825C LuoTianyi and the Show

    传送门(luogu) 传送门(CF) 前言 我来水题解力 简化题意 \(n\) 个人,\(m\) 个座位,每个人落座的方法有三种: 坐最左边的人的左边,没人的话就做 \(m\) 号座位,若最左边的为 ...

  8. 啊哈C语言案例学习笔记

    Hello World #include<stdio.h> /* 技术要点: 初学者在编写程序时,经常会忘记在语句后边添加分号, */ int main() { printf(" ...

  9. obloader 基于典型场景数据导入

    作者:刘书盛 热衷技术分享.编写技术文档 原创作品 oceanbase 数据库 原创内容未经授权不得随意使用,转载请联系小编并注明来源,谢谢! 预处理函数: 函数签名 返回类型 描述 LOWER(ch ...

  10. Cesium中监听MOUSE_MOVE事件获取经纬度和高度

    有时候在这个圆球上获取精确的经度纬度还不容易,特别是高度 还好在cesium提供了接口,看 let selft = this; const scene = this.viewer.scene; var ...