etcd项目结构
其中核心模块etcdserver,lease,mvcc,raft
整体架构
客户端层
包括clientv3和etcdctl等客户端,用户通过命令行或者客户端通过restful api降低了etcd客户端的使用复杂度。除此之外,客户端使用负载均衡和故障转的特性提供了高可用性。
API接口层
API接口层提供了客户端访问服务端的通信协议和接口定义,以及服务端节点之间的相互通信的协议。etcd v2版本使用基于http的restful api, etcd v3 使用gRPC通信协议。
etcd v3提供了grpc-gateway提供 restful代理,转换HTTP/JSON 请求为gRPC 的protocal buffer格式的消息。
etcd raft层
负责leader选举和日志复制等功能,除了与本节点的etcd通信之外,还与其他节点进行交互,实现分布式一致性。
逻辑层
etcd的业务逻辑层,包括鉴权,租约,KVserver,MVCC和Compactor压缩等核心功能特性。
etcd存储
实现了快照,预写式日志WAL(write ahead log)
etcd交互总览
通过读写数据来查看各个组件交互过程。
以下为etcd组件交互流程
客户端->API接口层->etcd Server ->etcd raft算法库
etcd Server
接收客户端的请求,在kvserver进行拦截,实现如日志,监控,校验等功能。etcd Server中的raft模块,用于与etcd-raft库进行通信。WAL预写式日志中保存了任期号,投票索引,提案内容等等。etcd根据wal中的内容,启动时恢复,以此来保持数据一致性。
etcd raft
raft库,raft log来保存单个节点的日志,存在内存中。raft库更重要的是负责与集群中的其他etcd server进行交互,实现分布式一致性。
- 首先是写数据到etcd节点中
- 其次是当前 etcd节点与集群中其他的 etcd节点之间进行通信,确认数据存储成功之后,回复客户端。
client->etcd交互流程
在raft中会将数据封装成raft日志的形式提交给raft模块。
在以上流程中,在raft协议中写入数据的etcd必定是leader节点,如果客户端提交数据到非 leader节点的时候,该节点需要将请求转发到etcd leader节点进行处理。
etcd->client应答流程
当多数etcd节点持久化日志数据成功并进行应答,提案的状态就会变成已提交。在应答某条日志数据是否已经提交的时候,raft会将日志先写入wal中,原因如下:
- 该过程仅仅添加一条日志,一方面开销小,速度会很快
- 另一方面,如果在后面applier V3写入失败,etcd服务端在重启的时候也可以根据wal模块中的日志数据进行回复。
raft模块中的raftlog数据在内存中存储,在服务重启后失效,客户端请求的数据则会被持久化保存到wal中,不会在重启后丢失。