5A
5A要求实现一个配置控制器,负责管理分片到集群的映射,以及集群变更后,新配置信息的生成。
实现起来比较简单,由于控制器本身也类似kvraft,要采用raft来维护各节点间的一致性,和lab4的实现差不多,差异点主要就是分片重分配策略的实现。按照文档要求,重分配策略需要满足以下需求:
- 所有分片都要分配给合法的集群Id(group id,GID)
- 负载均衡(集群间负责的分片数,相差不大于1)
- 移动分片的数量尽量少
- 结果确定性(同样的输入应该得到同样的输出,不能依赖map的遍历顺序)
因此,我们的重分配策略可以是:
- 计算每个集群应当负责的分片数量(分片数量/集群数量,无法整除的话把剩余分片分配给前几个集群)
- 从分片较多的集群中,拿出多余的分片分给分片数量少的集群
5B
5B最主要的功能就是,实现配置更新后的分片数据迁移功能。
以下是我的实现思路:
- 需要把配置变更看成是一条raft log,以同步group内所有server的配置信息
- 为shard设置状态机,区分正在拉取数据的shards(ShardPulling)以及可服务的shards(ShardServing);在配置信息更新时,更新shard状态
- 对于需要拉取数据的shards(ShardPulling),后台向指定的group发送RPC主动拉取数据
- 拉取到shard数据后,向raft提交一条merge数据的log,以同步group内所有server的shard数据
有个需要注意的点就是,在拉取shard数据时,去重表也要同步进行拉取。为什么呢?考虑这样一个场景:假设shard 1从Group 1迁移到Group2;G2开始拉取shard 1的数据;G1在配置变更前,对shard 1的请求有过执行(可能执行了一次Put/Append);G2的去重表不会记录这次操作;如果G2直接开始提供服务,可能就会重复执行客户端请求(破坏at-most-once语义)。
1602

被折叠的 条评论
为什么被折叠?



