服务器状态
严格来说,ectd节点有三种角色:Leader、Flower、Candidate。
Leader:复制处理所有与客户端的交互和数据处理,协调follower,只有一个; Follower:听从Leader差遣; Candidate:当没有Leader的时候,所有服务器可以竞选Leader,向其他服务器拉票; 节点角色会在以上三种角色中进行切换。
核心架构
etcd 整体架构图如所示。其中,etcd 有 etcd Server、gRPC Server、存储相关的 MVCC 、Snapshot、WAL,以及 Raft 模块。通过分层的方式,我们可以依次将其分为客户端层、API接口层、Raft层、逻辑层、数据存储层。
(1) 客户端层
客户端层包括clientv3 和 etcdctl 等客户端。用户通过命令行或者客户端调用提供了 RESTful 风格的 API,降低了 etcd 的使用复杂度。
除此之外,客户端层的负载均衡和节点间故障转移等特性也提升了 etcd 服务端的高可用性。
(2) API接口层
API 接口层提供了客户端访问服务端的通信协议和接口定义,以及服务端节点之间相互通信的协议。etcd 有V3和V2两个版本:
etcd V3使用 gRPC 作为消息传输协议;
etcd V2默认使用 HTTP/1.x 协议。
对于不支持 gRPC 的客户端语言,etcd 提供 JSON 的 grpc-gateway 。通过 grpc-gateway 提供 RESTful代理,转换 HTTP/JSON 请求为 gRPC 的 Protocol Buffer 格式的消息。
然而,值得注意的是,etcd V2 和 V3 是在底层使用同一套 Raft 算法的两个独立应用,但相互之间实现原理和使用方法上差别很大,接口不一样、存储不一样,两个版本的数据互相隔离。
(1) Raft层
Raft 层作为etcd关键的基础模块,主要负责 Leader 选举和日志复制等功能,除了与本节点的 etcd Server 通信之外,还与集群中的其他 etcd 节点进行交互,实现分布式一致性数据同步的关键工作。
(2) 逻辑层
etcd 的业务逻辑层,包括鉴权、租约、KVServer、MVCC 和 Compactor 压缩等核心功能特性。
(3) 数据存储层
数据存储层中主要实现了快照、预写式日志 WAL。
etcd 整体框架 读写总体概述 总览etcd各个模块间的交互,总体上的请求流程从上至下依次为客户端 → API 接口层 → etcd Server → etcd raft 算法库。
读请求执行流程 etcd 中一个读请求的具体执行流程如下:
首先,客户端会创建一个 clientv3 库对象,通过负载均衡算法选择一个 etcd 节点,使用 KVServer 模块的 API 来访问 etcd server; 然后,client 发送Range RPC请求到了server后就进入了KVServer模块; server 收到client的Range RPC请求后,根据ServiceName和RPC Method将请求转发到对应的handler实现; handler首先会将上面描述的一系列拦截器串联成一个拦截器再执行,在拦截器逻辑中,通过调用KVServer模块的Range接口获取数据。 在etcd读请求的核心,需要经过线性读 ReadIndex 模块、MVCC(包含 treeIndex 和 BlotDB)模块。 其中,线性读是相对串行读来讲的概念。集群模式下会有多个 etcd 节点,不同节点之间可能存在一致性问题,串行读直接返回状态数据,不需要与集群中其他节点交互。这种方式速度快,开销小,但是会存在数据不一致的情况。线性读则需要集群成员之间达成共识,存在开销,响应速度相对慢。但是能够保证数据的一致性,etcd 默认读模式是线性读。 写请求执行流程 etcd 一个写请求的完整执行流程,主要包括 Quota模块、KVServer模块、WAL模块、Apply模块和MVCC模块。
首先,client端通过负载均衡算法选择一个etcd节点,发起 gRPC 调用; 然后,etcd节点收到请求后经过gRPC拦截器、Quota 模块后,进入 KVServer 模块,Quota 模块用于校验 etcd db 文件大小是否超过了配额; KVServer模块向 Raft 模块提交一个提案,提案内容为“xxx”; 随后此提案通过 Raft HTTP 网络模块转发、经过集群多数节点持久化后,状态会变成已提交; Etcd server 从 Raft 模块获取已提交的日志条目,传递给 Apply 模块; Apply 模块通过 MVCC 模块执行提案内容,更新状态机。 与读流程不一样的是写流程还涉及 Quota、WAL、Apply 三个模块。此外,etcd 的 crash-safe 及幂等性也正是基于 WAL 和 Apply 流程的 consistent index 等实现的。