https://github.com/c-toast/6.824-golabs-2021
基础概念partition和replication是增强分布式系统可扩展性和两种手段。通过partition,每个节点只需维护部分shard的数据和请求,减轻了存储和处理压力。并且当client请求不同shard的数据时,不同shard可以并行提供服务,增加了整个系统的效率。通过replication,每个节点都维护了相同的数据,因而都具备处理客户(读)请求的能力。当出现大量读取相同数据的请求时,这些请求分发给若干个replica处理,有助于系统的负载均衡。除此之外,replication还有助于容错,即使部分节点宕机,其他节点依然可以提供服务。
MIT6.824 lab4 实现细节该实验要求实现具备partition和replication的key-value存储服务。系统分为若干个replication group,每一个replication group维护一个kv shard并对client提供该shard的读写服务。另外有一个replication group负责维护shard的配置信息,也就是记录各个shard分别由哪个replication group维护。replication group内部通过raft达成一致性。
lab 4A非常简单,在lab3上稍微改一改就好了。但lab 4B非常有挑战性。看完实验要求后,个人感觉如果完全自己做的话要花费不少的时间和精力。于是我决定先参考了别人的思路,弄清楚有哪些坑和注意点之后再尝试去实现。我主要参考了https://github.com/LebronAl/MIT6.824-2021的实现。
难点:
- 当配置更改时,各个replication group如何彼此配合,交换shard以符合配置要求。
- 如何判断和处理过时请求(例如读取在上一个配置中属于该replication group但在当前配置下不属于该replication group的key-value)和重复请求(例如重复更改配置,重复更新shard等)。
- 如何实现各个shard的管理,以避免不必要的依赖与阻塞。
实现细节:
- 创建若干个新的goroutine来定期检测配置更改,从其他replication group拉取shard,告知其他replication group删除已被拉取的旧shard。注意只有leader需要运行这些goroutine,然后leader再将运行的结果(例如新的配置,新的shard)写入日志,从而再整个replication group中完成相应的 *** 作。
- 每个shard维护一个状态,这些状态会被一些 *** 作例如配置更改,shard更新等更改。goroutine根据shard的状态决定下一步的 *** 作。
- 当接受到其他replication group的请求(例如拉取shard,删除shard)时,要判断配置序列号是否匹配。只有在匹配的序列号下,group与group之间才能正确地交互协作,实现shard状态的迁移。
- 所有 *** 作都应写入日志,包括配置更改,更新shard,读写请求等。根据这些 *** 作的顺序,决定哪些是过时请求和重复请求。日志中必须包含足够的信息例如新的shard信息,新的配置信息,以便节点回放日志。
- 为了防止shard数据被覆盖丢失,只有当旧shard确定被相关replication group接受时,才允许删除旧shard数据和进入下一轮的配置更改。
- 保证各个 *** 作的幂等性。在该实验下很难向前面的实验那样采用cache机制,但可以通过shard的状态,配置序列号等来判断该 *** 作是否已经被执行过。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)