raft理论与实践[6]-lab3a-基于raft构建分布式容错kv服务
准备工作
前言
- 在之前的文章中,我们实现了raft算法的基本框架
- 在本实验中,我们将基于raft算法实现分布式容错的kv服务器
- 客户端用于交互raft服务器
- kvraft/client.go文件用于书写我们的客户端代码,调用Clerk的Get/Put/Append方法为系统提供强一致性的保证
- 这里的强一致性指的是,如果我们一个一个的调用(而不是并发)Clerk的Get/Put/Append方法,那么我们的系统就好像是只有一个raft服务器存在一样,并且调用是序列的,即后面的调用比前面的调用后执行
- 对于并发调用,最终状态可能难以预料,但是必须与这些方法按某种顺序序列化后执行一次的结果相同
- 如果调用在时间上重叠,则这些调用是并发的。例如,如果客户端X调用Clerk.Put(),同时客户端Y调用Clerk.Append()
- 同时,后面的方法在执行之前,必须保证已经观察到前面所有方法执行后的状态(技术上叫做线性化(linearizability))
- 强一致性保证对应用程序很方便,因为这意味着所有客户端都看到相同的最新状态
- 对于单个服务器,强一致性相对简单。多台的副本服务器却相对困难,因为所有服务器必须为并发请求选择相同的执行顺序,并且必须避免使用最新状态来回复客户端
本服务实现的功能
- 本服务支持3种基本的操作,
Put(key, value)
, Append(key, arg)
, and Get(key)
- 维护着一个简单的键/值对数据库
Put(key, value)
将数据库中特定key的值绑定为value
Append(key, arg)
添加,将arg与key对应。如果key的值不存在,则其行为类似于Put
Get(key)
获取当前key的值
- 在本实验中,我们将实现服务具体的功能,而不必担心Raft log日志会无限增长
实验思路
- 对lab2中的raft服务器架构进行封装,封装上一些数据库、数据库快照、并会处理log的具体执行逻辑。
- 对于数据库执行的Get/Put/Append方法都对其进行序列化并放入到lab2 raft的体系中,这样就能保证这些方法的一致性
获取源代码
- 假设读者已经阅读了准备工作中的一系列文章
- 在此基础上我们增加了本实验的基本框架kvraft文件以及linearizability文件
- 读者需要在kvraft文件夹中,实验本实验的具体功能
- 获取实验代码如下
git clone git@github.com:dreamerjackson/golang-deep-distributed-lab.git
git reset --hard d345b34bc
客户端
- Clerk结构体存储了所有raft服务器的客户端
servers []*labrpc.ClientEnd