Github上下载etcdv3.5.9源代码,包含server和client两部分。
先放ETCDv3 读写流程图镇楼
读流程
写流程
Etcd Server
server->etcdmain->main.go:Main():startEtcdOrProxyV2() ->etcd.go:startEtcd()->StartEtcd()->etcdserver目录下server.go:NewServer() 初始化该节点为follow,创建管理lease(小顶堆)的lessor,WAL,MVCC,authStore,KV等等.
raft协议主要体现在etcd/raft/raft.go文件中,每个节点初始化为follower, 随机事件进入参选状态candidate并给自己投票,当获得多数票数后成为leader,并定时发送心跳。当其他follower收不到心跳时,该follower再次进入candidate.那这个leader发现了新的 Leader 任期号,那么它就需要转换到 Follower。etcd3.4引入PreVote预投票机制,防止原leader A Crash时,选出新leader,而当老leader A 恢复后再次触发新一轮 Leader 选举,影响服务的可用性。在这种情况下,因 A 节点数据落后较多,预投票请求无法获得多数节点认可,因此它就不会进入 Candidate 状态,导致集群重新选举。
存储数据库boltdb
etcd 数据存储在 boltdb, boltdb 基于 B+ tree、各类 page 实现查找、更新、事务提交. 核心数据结构包括page、node、bucket 等。
boltdb 文件指的是你 etcd 数据目录下的 member/snap/db 的文件, etcd 的 key-value、lease、meta、member、cluster、auth 等所有数据存储在其中。etcd 启动的时候,会通过 mmap 机制将 db 文件映射到内存,后续可从内存中快速读取文件中的数据。写请求通过 fwrite 和 fdatasync 来写入、持久化数据到磁盘。
boltdb 结构图
boltdb 提供了非常简单的 API 给上层业务使用,当我们执行一个 put hello 为 world 命令时,boltdb 实际写入的 key 是版本号,value 为 mvccpb.KeyValue 结构体。
Debug
- 在 etcd 3.4 中,logger 默认为 capnslog,trace 特性只有在当 logger 为 zap 时才开启,因此你需要设置 --logger=zap. 打开之后可以看到 range/put/txn 等操作的耗时。
- etcd 默认参数并不会采集各个接口的延时数据,我们可以通过设置 etcd 的启动参数 --metrics 为 extensive 来开启,获得每个 gRPC 接口的延时数据。同时可结合各个 gRPC 接口的请求数,获得 QPS。