MIT6.824 lab4B实验记录

news2024/12/27 10:44:27

Background

主要是完成一个可以根据group数量,动态调整shard所属的group的分布式kv键值引擎。其中shard->group的配置由shardctrler集群来管理,底层也是通过raft group来容错(分布式嘛)

然后这个shardkv就是要完成的是根据shardctrler管理的Config,来更新拉取和gc shard kv。

拉取Config

我们记录了lastconfig和currentconfig。因为我们的分片转移和切片gc要依赖旧的和新的config。

然后这个只允许config.Num递增,并且要求切片都是serving状态,也就是要完成了这一轮的切片转移和gc才行。保障了整个过程的完整性。

func (kv *ShardKV) applyConfiguration(nextConfig *shardctrler.Config) *CommandResponce {
	if nextConfig.Num == kv.currentConfig.Num+1 {
		DPrintf("Node{%v} group{%v} config apply success Num{%v} shards{%v}", kv.me, kv.gid, nextConfig.Num, nextConfig.Shards)
		kv.updateShardStatus(nextConfig)
		kv.lastconfig = kv.currentConfig
		kv.currentConfig = *nextConfig
		return &CommandResponce{"", OK}
	}
	DPrintf("Node{%v} group{%v} config apply fail Num{%v} {%v}", kv.me, kv.gid, nextConfig.Num, kv.currentConfig.Num+1)
	return &CommandResponce{"", ErrOutDated}
}

分片拉取过程

本实验的设计就是通过一个拉取协程和一个gc协程作为背景协程来做处理。applyConfig时我们先把切片标记一下,如果一个切片的最新gid是当前gid,并且旧版本没有,那么说明我们要到别的组里面拉取,所以我们把这个切片所属的状态机状态标记为Pulling。同理,新分片不属于目前group但旧分片属于,所以我们要将其状态设为BePulling.

func (kv *ShardKV) updateShardStatus(config *shardctrler.Config) {

	for i := 0; i < shardctrler.NShards; i++ {
		if config.Shards[i] == kv.gid && kv.currentConfig.Shards[i] != kv.gid {
			if kv.currentConfig.Shards[i] != 0 {
				kv.stateMachines[i].Status = Pulling
			}
		}
		if config.Shards[i] != kv.gid && kv.currentConfig.Shards[i] == kv.gid {
			if config.Shards[i] != 0 {
				kv.stateMachines[i].Status = BePulling
			}
		}
	}
}

拉取,通过一个协程来定时远程拉取,我们要旧的配置上的servers,因为我们是处于过渡期,然后我们要拉取完所有我切片才能往下,所以就用到了waitgroup

func (kv *ShardKV) migrationAction() {
	kv.mu.Lock()
	g2s := kv.getShardIDsByStatus(Pulling)
	var wg sync.WaitGroup
	for gid, shardsIDs := range g2s {
		DPrintf("Node{%v} start pulltask", kv.me)
		wg.Add(1)
		go func(servers []string, configNum int, shardIDs []int) {
			defer wg.Done()
			pullTaskRequest := ShardOperationRequest{configNum, shardIDs}
			for _, server := range servers {
				var pullTaskResponse ShardOperationResponce
				srv := kv.make_end(server)
				if srv.Call("ShardKV.GetShardsData", &pullTaskRequest, &pullTaskResponse) && pullTaskResponse.Err == OK {
					DPrintf("Node{%v} get pulltaskResponce", kv.me)
					kv.Execute(NewInsertSHardsCommand(&pullTaskResponse), &CommandResponce{})
				}
			}
		}(kv.lastconfig.Groups[gid], kv.currentConfig.Num, shardsIDs)
	}
	kv.mu.Unlock()
	wg.Wait()
}

拉取别的group时,我们要拉取kv存储,和clientinformation。同时我们不阻塞写入的话,我们应该应用kv的话是插入kv,而不是直接赋值。然后把把他标记为gcing,等待gcing协程来处理,同时也保障了serving状态才是默认状态,简单说,在waitgroup下,我们可以完成一轮migration和gc。

func (kv *ShardKV) applyInsertShards(shardsInfo *ShardOperationResponce) *CommandResponce {
	if shardsInfo.ConfigNum == kv.currentConfig.Num {
		for shardId, shardData := range shardsInfo.Shards {
			shard := kv.stateMachines[shardId]
			if shard.Status == Pulling {
				for key, value := range shardData {
					shard.KV[key] = value
				}
				shard.Status = Gcing
			} else {
				DPrintf("Node{%v} encounters duplicated shards insert", kv.me)
				break
			}
		}
		for clientId, client_info := range shardsInfo.ClientInformation {
			if info, ok := kv.clientInfomation[clientId]; !ok || info.CommandId < client_info.CommandId {
				kv.clientInfomation[clientId] = client_info
			}
		}
		return &CommandResponce{OK, ""}
	}
	DPrintf("Node{%v} rejects outdated shards", kv.me)
	return &CommandResponce{ErrOutDated, ""}

}


gc协程同理,我们来看看gc的shardkv状态转移吧。把之前的gcing转换成serving,然后把要清除的清除。在删除分片的 handler 中,首先仅可由 leader 处理该请求,其次如果发现请求中的配置版本小于本地的版本,那说明该请求已经执行过,否则本地的 config 也无法增大,此时直接返回 OK 即可,否则在本地提交一个删除分片的日志。

for _, shardId := range shardsInfo.ShardIDs {
			shard := kv.stateMachines[shardId]
			if shard.Status == Gcing {
				shard.Status = Serving
			} else if shard.Status == BePulling {
				kv.stateMachines[shardId] = NewShard()
			} else {
				DPrintf("Node{%v} encounters duplicated deletion", kv.me)
				break
			}
		}

shardkv状态变化图 

同时做了空日志优化,因为提交必须以当前任期的日志,有时候可能会被卡住,所以我们起一个协程定期做一个空日志,也可以加速提交。

分布式的探讨

还是通过raft日志来确保大多数同样,所以上面每个协程的行为都是通过raft日志传播,applier协程的applychan来确保大多数接收了,然后应用,然后对于上层快照保存的kv的哪些元素------------看哪些元素是command命名被应用后被修改的,这样快照传过去,就相当于command被应用了。所以这一个lab,我们要多保留currentconfig和lastconfig。

正确性证明

你可能怀疑,如果gc协程先执行了,那么Bepulling的那个将被拉取的kv不是被清空了吗,其实不然。下面的代码。

 实际上我们gc协程是在拉取端,所以我们发现其转为了gcing(实际上gcing状态还是挺重要的)

然后对远端(非拉取端的raft group里面的节点)的bepulling(因为拉取端是gcing,也就是远端被拉取了,可以放心删除远端了)清空,变serving,对本地gcing转serving, i然后才能向shardctrler拉取下一个config。还有一点我们对于是不是gcing的group to shards是上一个版本 lastconfig的,而kv.statemachine是这个上个版本往下个版本过度的,所以我们改为gcing,然后得到gid ,shardsId。实际上是上一个config的,所以我们可以找到bepulling。对于改变我们的gcing到serving的话,实际意义上,我们用的是拉取端的gcaction 对于shardId执行的。因为我们有两个地方都有kv.Execute。上面的是调用本地的gcing---->serving。

RPC对远端的才是bepulling------》清空,serving,如下面

 有人问,那不是本地执行了多次execute吗,其实不然,因为我们每次rpc都是group to shards。

实际上本地gcing转serving,实际上远程一样是分多次的。实际上还是多次了,因为我们这个有多个servers,还是多次,但是只有当对面服务器是leader时才行,所以就一次execute。

一些之前的误解

newchannel----》notifychann是和commandId配合,一个notify_chan只用一次,用完可以马上删除,减少内存占用。

还可以参考:

GitHub - 1797818494/MIT6.824: to build a distributed system based on raft, mapReduce and so on using go

MIT6.824-2021/lab4.md at master · OneSizeFitsQuorum/MIT6.824-2021 · GitHub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/514307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

哪些地方能发表计算机论文? - 易智编译EaseEditing

计算机科学领域是一个快速发展的领域&#xff0c;每年都会涌现出许多新的科技和新的研究成果。 为了保证研究成果的质量和可信度&#xff0c;科学家们通常会通过期刊来发表自己的研究成果。 SCI期刊是世界著名的科技期刊数据库&#xff0c;被认为是科技领域内的权威数据库之一…

docker 系列之 Dockerfile 文件里 cmd命令与entrypoint命令区别

文章目录 一、cmd&#xff1a;用法1&#xff1a;带有中括号的形式用法2&#xff1a;shell form&#xff0c;即没有中括号的形式 二、entrypoint&#xff1a;第一种&#xff1a;命令行模式&#xff0c;也就是带中括号第二种&#xff1a;shell模式 三、总结&#xff1a; 一、cmd&…

《人月神话》纪念典藏版撤下了以前的宣传语

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> 《人月神话》作者Frederick Phillips Brooks Jr. 于2022年11月17日逝世。 清华大学出版社近期将发行《人月神话》纪念典藏版。 新版的封底如下&#xff0c;宣传语更换成了…

CleanMyMac X4.13.2.dmg最新中文版下载

它是Mac上一款美观易用的系统优化清理工具&#xff0c;也是小编刚开始用Mac时的装机必备。它能够清理系统垃圾&#xff0c;提升电脑的运行速度&#xff0c;卸载许久不用的软件&#xff0c;使其变得如新机一般流畅。 CleanMyMac X是一款专业的Mac清理软件&#xff0c;可智能清理…

al智能改写工具-ai自动生成文章软件

随着互联网的发展&#xff0c;文章编辑在不断地向自动化、高效化方向进行转变&#xff0c;一款名叫“改稿神器”的工具应运而生。它可以帮助我们快速实现全自动批量改稿&#xff0c;做到没有错别字&#xff0c;自动优化语法&#xff0c;自动插入图片&#xff0c;严格按照标准的…

【腾讯云FinOps Crane 集训营】初识 FinOps Crane

前言&#xff1a; 有幸参加了腾讯云Finops Crane 集训营&#xff0c;学到了很多东西&#xff0c;现在将内容分享给大家。 Finops Crane &#xff1a;是一个基于 FinOps 的云资源分析与成本优化平台。 它的目标是希望在保证客户应用运行质量的前提下&#xff0c;实现极致的降本。…

web前端面试题汇总大全 -- 持续更新!

文章目录 一、html 系列 ⭐⭐⭐⭐⭐1、H5新增特性和css3新增特性&#xff1f; 二、css 系列 ⭐⭐⭐⭐⭐1、BFC的理解&#xff1f;2、说说你对盒模型的理解&#xff1f;3、如何实现元素⽔平垂直居中&#xff1f;4、CSS如何画⼀个三⻆形&#xff1f;原理是什么&#xff1f;5、说说…

二分查找基础篇-JAVA

文章目录 前言 大家好,我是最爱吃兽奶,这篇博客给大家介绍一下二分查找,我们先从最基本的开始讲解,再慢慢深入,把优化和变形也和大家说一下,那么,跟着我的步伐,我们一起去看看吧! 一、什么是二分查找? 二分查找(Binary Search)也称作折半查找 二分查找的效率很高,每查找一次…

Adam优化器及其变种的原理

本文将从SGD开始介绍Adam优化器的原理以及其变种的提出背景。 1、SGD的原理 SGD&#xff08;随机梯度下降法&#xff09;是基于最速梯度下降法的原理&#xff0c;假设我们存在损失函数&#xff0c;其中是要学习参数&#xff0c;定义如下的优化路径&#xff0c;使得损失函数值最…

Ray使用案例

Ray Use Cases Ray用例 本页索引了用于扩展ML的常见Ray用例。它包含了对博客、例子和教程的突出引用,也位于Ray文档的其他地方。 大型语言模型和生成型人工智能 大型语言模型(LLMs)和生成性人工智能正在迅速改变行业,并以惊人的速度要求计算。Ray为这些模型的扩展提供了…

我让ChatGPT用CSS3画一个皮卡丘,还是自己画的可爱

突然想到了小时候看过的动画片《皮卡丘》&#xff0c;于是突然就想&#xff0c;ChatGPT肯定也看过&#xff0c;他哪有不知道的东西啊&#xff0c;于是就想着让他帮我画一个&#xff0c;他画出来之后&#xff0c;我笑了&#xff0c;这啥玩意儿啊。 目录 一、第一次尝试让ChatGP…

智安网络|怎么预防大大小小的网络入侵及信息泄露?五招值得收藏

网络安全是一个涵盖广泛、变幻多端的领域。网络风险防范需要多种措施&#xff0c;从教育人员如何正确处理机密信息到定期检查系统的安全性。 在现代网络环境下&#xff0c;网络安全成为防护重点&#xff0c;网络环境下出现的安全隐患可能会直接影响业务&#xff0c;甚至生命财…

【fiddler+burp+雷神模拟器联动抓包】

0x00 常用抓包工具 常用的抓包工具​有fiddler、wireshark、httpwatch、 firebug、F12/等。抓包抓的是协议&#xff0c;fiddler抓的是HTTP、HTTPS协议&#xff0c;wireshark抓的是其他协议。fiddler、wireshark可以修改接口的参数和返回值&#xff0c;常用的F12调试工具只可以…

npm 知识点

1 ~会匹配最近的小版本依赖包&#xff0c;比如~1.1.3会匹配所有1.1.x版本&#xff0c;但是不包括1.2.0 ^会匹配最新的大版本依赖包&#xff0c;比如^1.3.4会匹配所有1.x.x的包&#xff0c;包括1.3.4&#xff0c;但是不包括2.0.0 *会匹配最新版本 2 ant-design/pro-table 前面…

EndNote X9 引用参考 单击文献编号,不能跳转到文尾文献列表处,咋解决?文献编号 不能跳转 ,怎么办?

文章目录 1 正常情况下 引用文献编号 是可以跳转的2 问题分析3 解决方法4 EndNote X9 插入参考文献常见问题总结5 EndNote X9 快速上手教程&#xff08;毕业论文参考文献管理器&#xff09; 1 正常情况下 引用文献编号 是可以跳转的 正确的插入文献后&#xff0c; 正常情况下&a…

公告 | FISCO BCOS v3.3.0发布,新增块内分片技术,单链性能突破10万TPS

FISCO BCOS开源社区一贯秉承开源、开放、联合共建的原则&#xff0c;致力于链接社区力量将FISCO BCOS打造成更加完美的区块链底层平台。 在社区通力协作下&#xff0c;FISCO BCOS v3.3.0已经发布&#xff0c;块内分片作为本次更新的核心亮点&#xff0c;实现了应用间交易执行的…

PyMuPDF pdf神奇处理工具

可将pdf转图片&#xff0c;图片转pdf&#xff0c;可拼接pdf&#xff0c;可提取固定的内容。 详细参考下面文章&#xff1a; PyMuPDF关键字标注&#xff1a;https://www.cnpython.com/qa/1436855 PyMuPDF去水印&#xff1a;https://sunnysab.cn/2022/06/29/Clean-Watermarks-…

BlockingQueue(阻塞队列)基本使用指南

概述 BlockingQueue 是 java.util.concurrent 包提供的用于解决并发生产者 - 消费者问题的最有用的类。 BlockingQueue 的特性是在任意时刻只有一个线程可以进行 take 或者 put 操作&#xff0c;并且 BlockingQueue 提供了超时 return null 的机制&#xff0c;在许多生产场景…

哪些行业适合开发微信小程序?

随着电子商务的进一步发展&#xff0c;很多行业都开始开发自己的系统软件&#xff0c;企图通过线上线下结合的方式来达到更好的宣传效果&#xff0c;拓客引流。微信小程序凭借成本低、使用方便等优点成为很多商家的首选。那么究竟哪些行业适合开发微信小程序呢&#xff1f; …

springboot项目,localhost:port 可以访问,但是外网IP:port不行

springboot 项目启动后&#xff0c;localhost:port 可以访问&#xff0c;但是外网IP:port不行 现象原因及解决方法解决方法&#xff1a;规则1&#xff1a;规则2&#xff1a;规则3&#xff1a; 现象 springboot项目&#xff0c;localhost:port 可以访问&#xff0c;但是外网IP:…