TinyKv Project3 PartA Multi-raft KV

2023-05-16

TinyKv Project3 PartA Multi-raft KV

  • 前言
  • Project3 PartA Multi-raft KV 文档翻译
  • Add / Remove
  • LeaderTransfer

前言

  Project3是整个项目最难的部分,3a是对3b的铺垫,比较简单,就是对之前的代码增加领导禅让

Project3 PartA Multi-raft KV 文档翻译

  在 Project2 中,你建立了一个基于Raft的高可用的kv服务器,做得很好!但还不够,这样的kv服务器是由单一的 raft 组支持的,不能无限扩展,并且每一个写请求都要等到提交后再逐一写入 badger,这是保证一致性的一个关键要求,但也扼杀了任何并发性。

在这里插入图片描述

  在这个项目中,你将实现一个带有平衡调度器的基于 multi Raft 的kv服务器,它由多个 Raft group 组成,每个 Raft group 负责一个单独的 key 范围,在这里被命名为 region ,布局将看起来像上图。对单个 region 的请求的处理和以前一样,但多个 region 可以同时处理请求,这提高了性能,但也带来了一些新的挑战,如平衡每个 region 的请求,等等。

这个项目有3个部分,包括:

  • 对 Raft 算法实现成员变更和领导变更
  • 在 raftstore 上实现Conf change和 region split
  • 引入 scheduler

PartA

  在这一部分中,你将在基本的 Raft 算法上实现成员变更和领导者变更,这些功能是后面两部分所需要的。成员变更,即conf变更,用于添加或删除 peer 到Raft Group,这可能会改变 Raft 组的法定人数,所以要小心。领导权变更,即领导权转移,用于将领导权转移给另一个 peer,这对平衡非常有用。

代码

  你需要修改的代码都是关于 raft/raft.go 和 raft/rawnode.go 的,也可以参见proto/proto/eraft.proto 以了解你需要处理的新信息。conf change 和 leader transfer 都是由上层程序触发的,所以你可能想从 raft/rawnode.go 开始。

实现领导者转移

  为了实现领导者的转移,让我们引入两个新的消息类型。MsgTransferLeader 和MsgTimeoutNow。为了转移领导权,你需要首先在当前领导上调用带有MsgTransferLeader 消息的 raft.Raft.Step,为了确保转移的成功,当前领导应该首先检查被转移者(即转移目标)的资格,比如:被转移者的日志是否为最新的,等等。如果被转移者不合格,当前领导可以选择放弃转移或者帮助被转移者,既然放弃对程序本身没有帮助,就选择帮助被转移者吧。如果被转移者的日志不是最新的,当前的领导者应该向被转移者发送 MsgAppend 消息,并停止接受新的 propose,以防我们最终会出现循环。因此,如果被转移者符合条件(或者在现任领导的帮助下),领导应该立即向被转移者发送 MsgTimeoutNow 消息,在收到 MsgTimeoutNow 消息后,被转移者应该立即开始新的选举,无论其选举超时与否,被转移者都有很大机会让现任领导下台,成为新领导。

实现成员变更

  这里要实现的 conf change 算法不是扩展Raft论文中提到的联合共识算法,联合共识算法可以一次性增加和/或移除任意 peer,相反,这个算法只能一个一个地增加或移除 peer,这更简单,更容易推理。此外,Conf Change从调用领导者的raft.RawNode.ProposeConfChange 开始,它将提出一个日志,其中pb.Entry.EntryType 设置为 EntryConfChange,pb.Entry.Data 设置为输入 pb.ConfChange 。当 EntryConfChange 类型的日志被提交时,你必须通过RawNode.ApplyConfChange 与日志中的 pb.ConfChange 一起应用它,只有这样你才能根据 pb.ConfChange 通过 raft.Raft.addNode 和 raft.Raft.removeNode 向这个Raft 子节点添加或删除 peer。

提示:

  • MsgTransferLeader 消息是本地消息,不是来自网络的。
  • 将 MsgTransferLeader 消息的 Message.from 设置为被转移者(即转移目标)。
  • 要立即开始新的选举,你可以用 MsgHup 消息调用 Raft.Step
  • 调用 pb.ConfChange.Marshal 来获取 pb.ConfChange 的字节表示,并将其放入 pb.Entry.Data。

Add / Remove

  在 raft 层中,这两各操作仅仅会影响到 r.Prs[ ],因此新增节点就加一个,删除节点就少一个。

  需要注意的是,在 removeNode 之后,Leader 要重新计算 committedIndex。正常情况下,节点收到 appendEntry 会返回一个 appendResponse,当 Leader 收到这个 appendResponse 时会视情况更新自己的 committedIndex。但是呢,如果在节点返回 appendResponse 就被 removeNode 了,那么 leader 就不知道本次 entries 的同步情况了,也就不会再去重算 committedIndex。

  在 TestCommitAfterRemoveNode3A 中,节点1(Leader)发送 entry3 给节点2,节点2还没有给回应就被 removeNode 了。此时集群中只剩一个节点,那么 entry3 肯定是算作大多数节点同步了的,理应被纳入 committedIndex 中,但是由于 leader 没有收到 appendResponse ,就不会更新 committedIndex ,导致出错。解决办法是,在 removeNode 之后,直接重算 committedIndex,当然也不能忘了向集群同步。

// addNode add a new node to raft group
func (r *Raft) addNode(id uint64) {
	// Your Code Here (3A).
	if _, ok := r.Prs[id]; !ok {
		r.Prs[id] = &Progress{Next: r.RaftLog.LastIndex() + 1}
		r.PendingConfIndex = None // 清除 PendingConfIndex 表示当前没有未完成的配置更新
	}
}

// removeNode remove a node from raft group
func (r *Raft) removeNode(id uint64) {
	// Your Code Here (3A).
	if _, ok := r.Prs[id]; ok {
		delete(r.Prs, id)
		// 如果是删除节点,由于有节点被移除了,这个时候可能有新的日志可以提交
		// 这是必要的,因为 TinyKV 只有在 handleAppendRequestResponse 的时候才会判断是否有新的日志可以提交
		// 如果节点被移除了,则可能会因为缺少这个节点的回复,导致可以提交的日志无法在当前任期被提交
		if r.State == StateLeader && r.maybeCommit() {
			log.Infof("[removeNode commit] %v leader commit new entry, commitIndex %v", r.id, r.RaftLog.committed)
			r.broadcastAppendEntry() // 广播更新所有 follower 的 commitIndex
		}
	}
	r.PendingConfIndex = None // 清除 PendingConfIndex 表示当前没有未完成的配置更新
}

LeaderTransfer

  • 非 Leader 收到 MsgTransfer 之后要移交给 Leader:非 Leader 节点无法进行 LeaderTransfer,但是应该把收到的 MsgTransfer 发送给自己的 Leader,从而保证集群的 Leader 转移。
//follower
case pb.MessageType_MsgTransferLeader:
	//Local Msg,用于上层请求转移 Leader
	//TODO Follower No processing required
	// 非 leader 收到领导权禅让消息,需要转发给 leader
	if r.Lead != None {
		m.To = r.Lead
		r.msgs = append(r.msgs, m)
	}
//candidate
case pb.MessageType_MsgTransferLeader:
	//Local Msg,用于上层请求转移 Leader
	//要求领导转移其领导权
	//TODO Candidate No processing required
	// 非 leader 收到领导权禅让消息,需要转发给 leader
	if r.Lead != None {
		m.To = r.Lead
		r.msgs = append(r.msgs, m)
	}
//leader
case pb.MessageType_MsgTransferLeader:
	//Local Msg,用于上层请求转移 Leader
	//要求领导转移其领导权
	//TODO project3
	r.handleTransferLeader(m)

  首先,raft 层多了两种 MsgType 为 MessageType_MsgTransferLeader 和 MessageType_MsgTimeoutNow。上层会发送该消息给 leader,要求其转换 leader,不过 project3a 没有上层,全是在 raft 层内部测试的。当 leader 要转换时,首先需要把 r.leadTransferee 置为 m.From,表明转换操作正在执行。接着,会判断目标节点的日志是否和自己一样新,如果是,就给它发一个 MsgTimeoutNow,如果不是,就先 append 同步日志,然后再发送 MsgTimeoutNow。当节点收到 MsgTimeoutNow 后,立刻开始选举,因为它的日志至少和原 leader 一样新,所以一定会选举成功。当 leader 正在进行转换操作时,所有的 propose 请求均被拒绝。

func (r *Raft) handleTransferLeader(m pb.Message) {
	// 判断 transferee 是否在集群中
	if _, ok := r.Prs[m.From]; !ok {
		return
	}
	// 如果 transferee 就是 leader 自身,则无事发生
	if m.From == r.id {
		return
	}
	// 判断是否有转让流程正在进行,如果是相同节点的转让流程就返回,否则的话终止上一个转让流程
	if r.leadTransferee != None {
		if r.leadTransferee == m.From {
			return
		}
		r.leadTransferee = None
	}
	r.leadTransferee = m.From
	r.transferElapsed = 0
	if r.Prs[m.From].Match == r.RaftLog.LastIndex() {
		// 日志是最新的,直接发送 TimeoutNow 消息
		r.sendTimeoutNow(m.From)
	} else {
		// 日志不是最新的,则帮助 leadTransferee 匹配最新的日志
		r.sendAppend(m.From)
	}
}

  在这里看到,如果走的是r.sendAppend(m.From),那么在什么时候继续进行禅让呢?在接收到日志复制的response的时候继续禅让。

func (r *Raft) handleAppendEntriesResponse(m pb.Message) {
	//...
	
	//3A
	if r.leadTransferee == m.From && r.Prs[m.From].Match == r.RaftLog.LastIndex() {
		// AppendEntryResponse 回复来自 leadTransferee,检查日志是否是最新的
		// 如果 leadTransferee 达到了最新的日志则立即发起领导权禅让
		r.sendTimeoutNow(m.From)
	}
}

func (r *Raft) sendTimeoutNow(to uint64) {
	r.msgs = append(r.msgs, pb.Message{MsgType: pb.MessageType_MsgTimeoutNow, From: r.id, To: to})
}

  在接收到timeout后立刻开始进行选举

//follower
case pb.MessageType_MsgTimeoutNow:
	//Local Msg,节点收到后清空 r.electionElapsed,并即刻发起选举
	r.handleTimeoutNowRequest(m)
}

func (r *Raft) handleTimeoutNowRequest(m pb.Message) {
	if _, ok := r.Prs[r.id]; !ok {
		return
	}
	// 直接发起选举
	if err := r.Step(pb.Message{MsgType: pb.MessageType_MsgHup}); err != nil {
		log.Panic(err)
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TinyKv Project3 PartA Multi-raft KV 的相关文章

  • Multi-Language IDE for Professional Developers (Komodo)

    Komodo is the professional IDE for major web languages including Python PHP Ruby Perl HTML CSS and JavaScript You 39 ll
  • BoT-SORT: Robust Associations Multi-Pedestrian Tracking

    BoT SORT Robust Associations Multi Pedestrian Tracking 论文 xff1a arxiv code github 数据 xff1a 还未找到 文章贡献 运动相机的补偿和卡尔曼状态向量的选择I
  • CIKM-2021 Multi-Factors Aware Dual-Attentional Knowledge Tracing

    前言 首先说一下自己读这篇文章的感受 xff0c 通过读文章题目 xff0c 我们可以得知 这篇文章的主要创新点就在于multi factors和dual attention 文章的思路也很清晰 xff0c 首先就是介绍多factor是哪些
  • 论文笔记:MPRNet: Multi-Stage Progressive Image Restoration

    相关方法 单阶段 多阶段 注意力 方法 将图像分割为不重叠的patches xff1a 四个用于第一阶段 xff0c 两个用于第二阶段 xff0c 原始图像用于最后一阶段 残差学习 xff1a X S 61 I
  • roslaunch px4 multi_uav_mavros_sitl_sdf.launch报错

    转载自 xff1a https www cnblogs com pig fly p 13971458 html 在试图运行multi uav mavros sitl sdf launch时报错 xff1a while processing
  • ethzasl_msf(multi-sensor fusion)传感器融合定位算法解析

    瑞士苏黎世大学Stephen Weiss对基于EFK松耦合传感器融合定位研究非常深入 xff0c 以下是他的相关论文和开源代码 xff0c 可以详细阅读 xff0c 最后附上了本人阅读的相关博客 1 论文 1 Vision Based Na
  • Multi-Object Trackers

    Introduction to Multiple Target Tracking 简单介绍了多目标物跟踪的流程 方法 1 single target tracking STT 单目标跟踪 xff0c 不需要association和assig
  • vue/multi-word-component-names

    解决方法一 xff1a vue config js中添加一行 xff08 这种方式试完还是有报错显示 xff0c 但是项目可以运行 xff09 span class token keyword const span span class t
  • 论文超详细精读:SMPL: A Skinned Multi-Person Linear Model

    文章目录 前言总览一 Introduction二 Related WorkBlend Skinning xff08 混合蒙皮 xff09 Blend shapes xff08 混合变形 xff09 Learning pose and sha
  • TinyKv Project1 Standalone KV

    TinyKv Project1 Standalone KV 前言Project1 StandaloneKV 文档翻译文档的重点内容StandAloneStorageWriteReader Server单元测试 前言 project1还是比较
  • TinyKv Project2 PartA RaftKV

    TinyKv Project2a RaftKV 前言Project2 RaftKV 文档翻译Project2A重点内容抛出RaftLogRaftLog结构体字段详解RaftLog核心函数详解 RaftRaft 驱动规则Msg的作用与含义Ms
  • TinyKv Project3 PartA Multi-raft KV

    TinyKv Project3 PartA Multi raft KV 前言Project3 PartA Multi raft KV 文档翻译Add RemoveLeaderTransfer 前言 Project3是整个项目最难的部分 xf
  • TinyKv Project3 PartC Multi-raft KV

    TinyKv Project3 PartC Multi raft KV 前言Project3 PartC Multi raft KV 文档翻译processRegionHeartbeatSchedule 前言 3C要求我们实现调度 3c按照
  • Raft算法的Java实现

    自己这几天在看Redis的Sentinel高可用解决方案 Sentinel选主使用的是著名的Raft一致性算法 本文对Raft的选主作了介绍 具体的算法内容 请参考 Raft 论文 Raft的整体结构 Raft 通过选举一个高贵的领导人 然
  • etcd 集群搭建及常用场景分析

    概述 etcd 是一个分布式一致性k v存储系统 可用于服务注册发现与共享配置 具有以下优点 简单 相比于晦涩难懂的paxos算法 etcd基于相对简单且易实现的raft算法实现一致性 并通过gRPC提供接口调用 安全 支持TLS通信 并可
  • 如何将新的 Orderer 组织添加到现有的 Hyperledger Fabric 网络

    我正在尝试向基于 RAFT 的现有订购服务添加一个新的订购者组织 我正在使用first network from fabric samples作为基础网络 在生成加密材料时 我进行了修改 为另外 1 个订购者组织生成加密材料 这crypto
  • paxos 与 raft 进行领导者选举

    读完paxos和raft paper后 我有以下困惑 paxos论文仅描述了单个日志条目的共识 相当于raft算法中的领导者选举部分 在raft的leader选举中 paxos的方式相对于简单的随机超时方式有什么优势呢 一个常见的误解是原始
  • 在 RAFT 中,是否有可能对某个日志条目达成多数共识,但该条目尚未提交?

    考虑一下官方的这个模拟筏网页 https raft github io Why is term 2 index 1尽管没有承诺S2 leader S3 and S4同意日志吗 我运行了几分钟以确保所有通信均已完成 奇怪的是 如果我再添加一个
  • 网络断开后,raft follower如何重新加入?

    我在木筏上遇到了问题 在论文 寻找一种可理解的共识算法 扩展版 中写道 要开始选举 追随者会增加其当前的 任期并过渡到候选状态 第 5 2 节 它还说 AppendEntries RPC 和 RequestVot RPC 中的接收者应为 R
  • 与恶霸算法相比,高级主选举算法有什么好处?

    我读过当前的主选举算法 如 Raft Paxos 或 Zab 如何在集群上选举主节点 但不明白为什么他们使用复杂的算法而不是简单的恶霸算法 我正在开发一个集群库并使用 UDP 多播来发送心跳消息 每个节点加入一个多播地址 并定期向该地址发送

随机推荐

  • 配置目标跟踪开源项目traj_gen_vis踩过的坑

    项目地址 https github com icsl Jeon traj gen vis 安装依赖需注意的问题 traj gen with qpoases 需安装ros分支的代码 xff08 这个作者并没有指出 xff0c 坑 xff09
  • cmake arm-none-eabi-gcc for stm32 cpp project

    尝试把原有的stm32工程F1canBootloader用cmake来管理 xff0c 遇到了以下几个坑 xff1a 1 报错 xff0c undefined reference to 96 dso handle 39 CMakeFiles
  • 网络攻防之wireshark抓取登录信息

    使用wireshark抓取登录信息 简介 xff1a Wireshark xff08 前称Ethereal xff09 是一个网络封包分析软件 网络封包分析软件的功能是撷取网络封包 xff0c 并尽可能显示出最为详细的网络封包资料 Wire
  • 头文件互相包含所引发的的问题(深入剖析)

    今天写程序出现了一个让人蛋疼的错误 xff0c 后来发现是由于头文件互相包含所引起的 原本只是简单的以为头文件互相包含只会触发 xff0c 头文件的递归包含 即 xff0c A包含B xff0c 所以才A的头文件里会将B的头文件内容拷贝过来
  • C++11异步操作future和aysnc 、function和bind

    C 43 43 11异步操作future和aysnc function和bind 前言异步操作std future和std aysnc 介绍std future和std aysnc的使用Demostd packaged task 介绍std
  • C++文件服务器项目—FastDFS—1

    C 43 43 文件服务器项目 FastDFS 1 前言1 项目架构2 分布式文件系统2 1 传统文件系统2 2 分布式文件系统 3 FastDFS介绍3 1 fdfs概述3 2 fdfs框架中的三个角色3 3 fdfs三个角色之间的关系3
  • C++文件服务器项目—Redis—2

    C 43 43 文件服务器项目 Redis 2 前言1 数据库类型1 1 基本概念1 2 关系 非关系型数据库搭配使用 2 redis基础知识点2 1 redis安装2 2 redis中的两个角色2 3 redis中数据的组织格式2 4 r
  • C++文件服务器项目—Nginx—3

    C 43 43 文件服务器项目 Nginx 3 前言1 Nginx一些基本概念1 1 Nginx初步认识1 2 正向代理概念理解1 3 反向代理概念理解 2 Nginx的安装与配置2 1 Nginx与相关依赖库的安装2 2 Nginx相关的
  • C++文件服务器项目—FastCGI—4

    C 43 43 文件服务器项目 FastCGI 4 前言1 CGI 概念理解2 FastCGI 概念理解3 FastCGI和spawn fcgi安装4 FastCGI和 Nginx的关系5 Nginx数据转发 修改配置文件6 spawn f
  • C++文件服务器项目—Nginx+FastDFS插件—5

    C 43 43 文件服务器项目 Nginx 43 FastDFS插件 5 前言1 文件上传下载流程1 1 文件上传流程1 2 文件下载流程1 3 文件下载优化流程 2 Nginx和fastDFS插件2 1 安装Nginx和fastdfs n
  • C++文件服务器项目—数据库表设计 与 后端接口设计—6

    C 43 43 文件服务器项目 数据库表的设计 6 前言1 数据库建表1 1 用户信息表 user info1 2 文件信息表 file info1 3 用户文件列表表 user file list1 4 用户文件数量表 user file
  • C语言中宏定义的使用

    1 引言 预处理命令可以改变程序设计环境 提高编程效率 它们并不是 C 语言本身的组成部分 不能直接对 它们进行编译 必须在对程序进行编译之前 先对程序中这些特殊的命令进行 预处理 经过预处理后 程序就不再包括预处理命令了 最后再由编译程序
  • C++文件服务器项目—项目总结与反向代理—7

    C 43 43 文件服务器项目 项目总结与反向代理 7 1 项目总结2 项目提炼3 web服务器的反向代理4 存储节点的反向代理 组件介绍基本写完了 xff0c 后续进行深入 本专栏知识点是通过零声教育的线上课学习 xff0c 进行梳理总结
  • https相关内容

    https相关内容 前言基础概念理解https传输过程 前言 本文写https相关内容 xff0c 持续补充 基础概念理解 对称加密 加解密秘钥是同一个 非对称加密 公钥 私钥 sa gt 公钥私钥都是两个数字ecc gt 椭圆曲线 两个点
  • TinyKv介绍

    TinyKv介绍 前言tinykv架构代码结构如何去写TinyKv参考内容 前言 开一个新坑 xff0c 将tinykv的4个project全部实现 虽然今天我点进去看的时候就萌生退意 好在没有放弃之前 xff0c 把project1完成了
  • TinyKv Project1 Standalone KV

    TinyKv Project1 Standalone KV 前言Project1 StandaloneKV 文档翻译文档的重点内容StandAloneStorageWriteReader Server单元测试 前言 project1还是比较
  • TinyKv Project2 PartA RaftKV

    TinyKv Project2a RaftKV 前言Project2 RaftKV 文档翻译Project2A重点内容抛出RaftLogRaftLog结构体字段详解RaftLog核心函数详解 RaftRaft 驱动规则Msg的作用与含义Ms
  • TinyKv Project2 PartB RaftKV

    TinyKv Project2 PartB RaftKV 前言Project2 PartB RaftKV 文档翻译PartB 到底想让我们做什么 xff1f 分析要实现的函数到底要干什么事情proposeRaftCommand 将上层命令打
  • TinyKv Project2 PartC RaftKV

    TinyKv Project2 PartC RaftKV 前言Project2 PartC RaftKV 文档翻译raft节点如何自动的compact压缩自己的entries日志生成快照与快照收收发日志压缩与快照收发总结疑难杂症 前言 pr
  • TinyKv Project3 PartA Multi-raft KV

    TinyKv Project3 PartA Multi raft KV 前言Project3 PartA Multi raft KV 文档翻译Add RemoveLeaderTransfer 前言 Project3是整个项目最难的部分 xf