MIT 6.824 lab4A总结

news2024/10/7 9:23:03

Background

一个raft集群的性能很明显和raft的数量有关系,更重要的是如果我们多个key放在一个raft集群里,这样的并行性不太好。所以我们可以考虑分片,利用操作潜在的并行性来提升性能。每一个副本组只管理几个分片的put和get,并且组之间并行操作;因此总的系统吞吐量(单位时间的put和get)与组的数量成比例增加。这个实验就是对raft group和分片的所在的group做一个协调控制的。

挑战

该lab的一个主要挑战是处理重新配置——在分配分片到组的变化。在单个副本组中,所有的组成员必须在当重新配置关系到客户端的Put/Append/Get请求的时候达成一致。例如,一个Put请求可能与导致副本组停止对保存的Put键的分片负责的重新配置通知到达。组内的所有副本必须就Put是在重新配置之前还是之后发生达成一致。如果是在之前,Put应该生效,分片的新所有者应该看到其效果;如果之后,Put请求不应该生效以及客户端必须在新的所有者处进行重试。建议的方法是去让每个副本组使用Raft去记录Put/Append/Get的顺序以及重新配置的顺序。你将需要确保在任何时候最多只有一个副本组为每一个分片服务

shard 只对应于一个 raft group。一个raft group可以在备份多个shard

实现

为了保障每个副本看到的配置都一样,我们采用了raft command日志来保障线性一致性,也就是1)对所以副本看到的配置都是一样的,2)而且读能看到最新的写。实际上完全可以仿造lab3来实现

主要map的访问是不确定顺序的,我们可以把这个他按key排序,这样每个副本对map的操作就是都是一样的了。Go中的map是引用的。如果您将一个一个map类型的变量分配给了另一个变量,那么两个变量将引用同一个map。因此,如果希望基于以前的配置创建一个新的Config,你需要创建一个新的map对象(使用make())以及分别复制键值

主要说一下leave和join方法

join:就是加入几个raft组,为了有比较好的扩展性,在join的时候,我们根据shards反向计算出group ----》shards这个map,然后不断的取最大的和最小的组,如果他们之间的差大于1的话,就从最大的组给最小的组一个shard控制权。可以将 shard 分配地十分均匀且产生了几乎最少的迁移任务。

leave:就是移除几个raft组,同样我们要动态挑战shards与group的关系,把一些没有组,也就是被移除raft组的shards,一个一个分配给最小的shards num的raft group来挑战。


func (sm *StateMachine) Join(gid_servers map[int][]string) {
	DPrintf("join {%v}", gid_servers)
	latest_config := sm.Configs[len(sm.Configs)-1]
	new_config := Config{len(sm.Configs), latest_config.Shards, deep_copy(latest_config.Groups)}
	for gid, servers := range gid_servers {
		if _, ok := new_config.Groups[gid]; !ok {
			new_servers := make([]string, len(servers))
			copy(new_servers, servers)
			new_config.Groups[gid] = new_servers
		}

	}
	g2s := Group2Shards(&new_config)
	for {
		min_gid, max_gid := GetGIDWithMinNumShards(g2s), GetGIDWithMaxNumShards(g2s)
		DPrintf("min_gid{%v} max_gid{%v}", min_gid, max_gid)
		if len(g2s[max_gid])-len(g2s[min_gid]) <= 1 {
			break
		}
		g2s[min_gid] = append(g2s[min_gid], g2s[max_gid][0])
		g2s[max_gid] = g2s[max_gid][1:]
	}
	var Shards [NShards]int
	for gid, shards := range g2s {
		for _, shard := range shards {
			DPrintf("shared{%v} -----> gid{%v}", shard, gid)
			Shards[shard] = gid
		}
	}
	new_config.Shards = Shards
	DPrintf("join group len{%v}", len(new_config.Groups))
	sm.Configs = append(sm.Configs, new_config)
}

func (sm *StateMachine) Leave(gids []int) {
	DPrintf("leave %v", gids)
	config_last_copy := sm.Configs[len(sm.Configs)-1]
	newConfig := Config{len(sm.Configs), config_last_copy.Shards, deep_copy(config_last_copy.Groups)}
	g2s := Group2Shards(&newConfig)
	orphanShards := make([]int, 0)
	for _, gid := range gids {
		delete(newConfig.Groups, gid)

		if shards, ok := g2s[gid]; ok {
			orphanShards = append(orphanShards, shards...)
			delete(g2s, gid)
		}
	}
	var newShards [NShards]int
	if len(newConfig.Groups) != 0 {
		for _, shard := range orphanShards {
			target := GetGIDWithMinNumShards(g2s)
			g2s[target] = append(g2s[target], shard)
		}
		for gid, shards := range g2s {
			for _, shard := range shards {
				newShards[shard] = gid
			}
		}
	}
	newConfig.Shards = newShards
	sm.Configs = append(sm.Configs, newConfig)

}

论文关于一个raft集群配置更改部分的讨论(不是实验部分,实验是多个raft集群与shard调节的实现)

一般情况下,可能导致两个leader,因为集群的大多数的定义发生了变化。

可以采用两阶段的方法

 

同时一个新加入的raft节点要比较长时间才能追赶上leader,为了减低提交的延时,在没有追赶上leader之前没有表决权

删除集群时,被删节点超时,变了candidte, 发出高term的requestvote,将leader变了follower将导致集群频繁不可用

 raft bug

map不可比,!=也不行。对于日志条目是否相等的判断,我们不应该加上command,直接根据log的term和index就行了!

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

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

相关文章

网络基础设施 拥塞控制

我经常说&#xff0c;传统的 TCP 优化已经到顶&#xff0c;不会有大意义了&#xff0c;这有两方面意思。 一方面&#xff0c;内在的&#xff0c;TCP 的 ACK 时钟带回的信息就那么多&#xff0c;用足了又能怎样。一个学习最差的差生能控制的分数是是 0&#xff5e;100 分的区间…

【Linux】基础IO——文件系统|软硬链接|动静态库

文章目录 一、磁盘1. 物理结构2. 存储结构3. 逻辑抽象结构 二、文件系统1. 文件系统的结构2. 查看文件3. 删除文件 三、软硬链接1. 软链接2. 硬链接3. ACM 时间 四、动静态库1. 动静态库的介绍2. 静态库的制作3. 动态库的制作4. 动态库的加载 一、磁盘 基于上篇博客所写到的文…

从0搭建Vue3组件库(十一): 集成项目的编程规范工具链(ESlint+Prettier+Stylelint)

欲先善其事,必先利其器。一个好的项目是必须要有一个统一的规范,比如代码规范,样式规范以及代码提交规范等。统一的代码规范旨在增强团队开发协作、提高代码质量和打造开发基石,所以每个人必须严格遵守。 本篇文章将引入 ESLintPrettierStylelint 来对代码规范化。 ESlint ES…

【计算机网络】学习笔记:第三章 数据链路层(八千字详细配图)【王道考研】

基于本人观看学习b站王道计算机网络课程所做的笔记&#xff0c;不做任何获利 仅进行交流分享 特此鸣谢王道考研 若有侵权请联系&#xff0c;立删 如果本篇笔记帮助到了你&#xff0c;还请点赞 关注 支持一下 ♡>&#x16966;<)!! 主页专栏有更多&#xff0c;如有疑问欢迎…

redhat 8.7 安装oracle 11g-11.2.0.4

redhat 8.7 安装oracle 11g-11.2.0.4 1、写在前面&#xff1a;这篇文章最后安装失败了。这是一次失败的尝试&#xff0c;仅做记录。结论是RHEL 8不支持Oracle 11g-11.2.0.4 安装&#xff0c;后续再研究怎么跑起来。1、数据库下载和安装文档1.1、查看oracle 11g 适合安装的linux…

阿里云版GPT官宣,我们问了它10个问题

4月7日&#xff0c;阿里云宣布自研大模型“通义千问”&#xff0c;目前已开始邀请用户测试体验。 阿里达摩院在NLP自然语言处理等前沿科研领域早已布局多年&#xff0c;并于2019年启动大模型研发&#xff0c;通义千问便是其最新成果&#xff0c;相当于阿里云版的“ChatGPT”。 …

让GPT成为护理专家 - 护士的工作如此简单

引子    书接上文《GPT接入企微应用 - 让工作快乐起来》&#xff0c;我把GPT接入了企微应用&#xff0c;不少同事都开始尝试起来了。有的浅尝辄止&#xff0c;有的刨根问底&#xff0c;五花八门&#xff0c;无所不有。这里摘抄几份&#xff1a; “帮我写一份表白信&#xff…

【Prompt】7 个向 chatGPT 高效提问的方法

欢迎关注【youcans的 AIGC 学习笔记】原创作品 【Prompt】7 个向 chatGPT 高效提问的方法 0. 向 chatGPT 高效提问的方法1. 提问方法&#xff1a;明确问题2. 提问方法&#xff1a;简洁清晰3. 提问方法&#xff1a;避免歧义4. 提问方法&#xff1a;提供上下文5. 提问方法&#x…

很不错的一篇文章,值得点赞收藏,带你全面了解MySQL性能调优、错误代码总结和全局参数配置(持续更新中ing)

前言 本文主要介绍当前MySQL性能优化原理实战&#xff0c;包括以下方面&#xff1a; 已更新文章目录MySQL遇到的的错误及解决方法全局参数文件配置详解。 后续希望大家提出宝贵的建议。喜欢的话点赞收藏关注走一波。如有错误的地方&#xff0c;请指出&#xff01;&#xff01;&…

C51 - 自写操作系统

最简OS 1> 版本1&#xff1a;任务建立与切换2> 版本2&#xff1a;定时器切换2.1> main.c2.2> task.c2.3> sleep.c 3> 版本3&#xff1a;加时间片轮转 在51单片机上&#xff0c;实现操作系统最简模型&#xff0c; 学习理解操作系统的基本概念&#xff1b; &am…

〖Python网络爬虫实战㉑〗- 数据存储之JSON操作

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

912. 排序数组

1.题目&#xff1a; 2.我的代码&#xff1a; C语言&#xff1a; /*** Note: The returned array must be malloced, assume caller calls free().*/ int* sortArray(int* nums, int numsSize, int* returnSize) {//希尔排序int gap numsSize;//多次预排while (gap > 1) {/…

【Linux】初识Linux

目录 &#x1f34e;一.Linux历史&#x1f34e; 1.UNIX发展的历史 2.Linux发展历史 &#x1f34f;二.开源&#x1f34f; &#x1f351;三.官网&#x1f351; &#x1f34a;四.企业应用现状&#x1f34a; 1.Linux在服务器领域的发展 2.Linux在桌面领域的发展 3.Linux在移…

自实现朴素贝叶斯分类器with案例:基于SMS Spam Collection数据集的广告邮件分类

目录 贝叶斯分类器何为朴素案例&#xff1a;基于SMS Spam Collection数据集的广告邮件分类SMS数据集词向量表示Laplacian平滑训练过程分类过程 完整代码 贝叶斯分类器 首先要理解贝叶斯决策的理论依据&#xff0c;引用西瓜书上的原话&#xff1a;对于分类任务&#xff0c;在所…

【小呆的力学笔记】非线性有限元的初步认识【二】

文章目录 1.2 有限元分析的数学原理1.2.1 基于最小势能原理的变分法提法1.2.1.a 弹性力学方程简化记法1.2.1.b 应变能密度和应变余能密度1.2.1.c 最小势能原理变分基础 1.2 有限元分析的数学原理 书接上回&#xff0c;我们已经回顾了线性有限元分析的理论基础——线弹性力学的…

TryHackMe-Lunizz CTF(boot2root)

Lunizz CTF 端口扫描 循例nmap Web枚举 进80&#xff0c;apache默认页面 gobuster扫一下目录 /hidden一个文件上传点, 图片上传后无权访问/hidden/uploads/ /whatever一个假的命令执行点 /instructions.txt 由 CTF_SCRIPTS_CAVE 制作&#xff08;不是真实的&#xff09;感谢…

如何看待人工智能技术的变革与未来?

人工智能是当今科技领域中最具前景的技术之一。从最初的逻辑推理到现在的深度学习&#xff0c;人工智能技术的发展已经经历了多个阶段。在本文中&#xff0c;我们将从技术的角度&#xff0c;探讨人工智能的发展历程和未来发展趋势。 一、起源和逻辑推理阶段 人工智能的起源可…

【五一创作】Java 反射

在了解反射前&#xff0c;我们先要知道一些相关知识 Class类 Class类的实例表示java应用运行时的类或接口&#xff0c;每个java类运行时都在JVM里表现为一个class对象&#xff0c;可通过类名.class、类型.getClass()、Class.forName("类名")等方法获取class对象。 …

关于 IO、存储、硬盘和文件系统

关于IO、存储、硬盘和文件系统 0.引入1.了解IO1.1.存储器IO1.2.设备IO 2.存储介质和存储类型2.1.内存2.2.硬盘2.3.固态硬盘&#xff08;SSD&#xff09;2.4.U盘 3.硬盘的工作原理3.1.磁头3.2.盘片3.3.电动机3.4.硬盘的读写操作 4.文件系统概述4.1.文件系统的类型4.2.文件系统的…

vagrant virtualbox 复制

菜鸟学习&#xff0c;记录一下 vagrant virtualbox 虚拟机复制。 目录 第一步&#xff0c;使用 virtualbox 复制虚拟机 第二步&#xff0c;复制 vagrant 文件 第三步&#xff0c;重命名相关文件夹及文件并修改配置&#xff1a; 第四步&#xff0c;注册运行复制后的虚拟机 第…