etcd raft
1 环境
https://github.com/etcd-io/etcd/releases/tag/v3.5.18
raftexample 是 etcd 提供的一个使用 etcd raft 共识算法库的示例。raftexample 最终实现了一个对外提供 REST API 的分布式键值存储服务。
2 代码结构
raftexample 的结构非常简洁,其主要文件如下:
main.go: 负责 raft 模块,httpapi 模块和 kvstore 模块之间的交互方式的组织;
raft.go: 提供网络基础通信、raft 协议推进执行能力。
httpapi.go: 向客户端 client 提供服务,主要提供 Get、Put、Post、Delete 接口服务。这三个服务的作用分别是检索KV、存储KV、新增 raft 节点、删除 raft 节点。
kvstore.go: 提供持久化存储功能。raft 协议本身并不提供存储能力,所以所有的 KV 最终的归属是这个kvstore。
get post delete put
| | | |
| | | |
+-V-----V--------------V-----V--+
| HTTP Service |
+------+------------------------+
|
|
+------V------+ ---> +----------+
| KVStore | | raftNode |
+-------------+ <--- +----------+
首先 client 向 raft 节点发送请求,假设调用 Put 方法,存储一个新的 kv。
节点收到这个请求之后,将 KV 对传递给 kvstore。
kvstore 拿到 kv 之后,并不急着将其进行持久化存储,而是将这个 kv 投递给 raftNode,
通过 raftNode 对这个 kv 进行决议,决议通过后,再将这个 kv 回送给 kvstore。
最后 kvstore 进行持久化存储。3 代码实现
3.1 http service
http service 的实现比较简单,它自定义了 httpKVAPI 结构体,其重写了 ServeHTTP 方法。然后通过serveHttpKVAPI 方法启动服务。需要注意的是,其内部持有 kvstore 对象,Get 方法和 Put 方法分别调用了 kvstore 的 Propose 方法和 Lookup 方法。
3.2 kvstore
kvstore 的定义中,kvStore 是存储结构,用了简单的 map 进行存储。mu负责多线程同步。除此之外,还有两个非常关键的属性,分别是 proposeC 管道和 snapshotter。这个结构说明,如果要实现一个kvstore,除了基本的存储结构之外,至少还需要一个管道和一个 snapshotter。
kvstore 和raftNode 之间使用了三个管道,分别是 proposeC(提议)、commitC、errorC。
kvstore使用proposeC将从http service传来的数据提交给raftNode;
raftNode将通过决议的数据,从commitC回送给kvstore。异常信息通过errorC进行传输。
3.3 raftNode
Last updated