etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程
1. etcd 項(xiàng)目結(jié)構(gòu)和功能
etcd 項(xiàng)目代碼的目錄結(jié)構(gòu)如下:
$ tree
├── auth
├── build
├── client
├── clientv3
├── contrib
├── embed
├── etcdctl
├── etcdmain
├── etcdserver
├── functional
├── hack
├── integration
├── lease
├── logos
├── mvcc
├── pkg
├── proxy
├── raft
├── scripts
├── security
├── tests
├── tools
├── vendor
├── version
└── wal
每個(gè)模塊的功能如下:
etcd 核心的模塊有 lease、mvcc、raft、etcdserver,其余都是輔助的功能。其中 etcdserver 是其他模塊的整合。
2. etcd 整體架構(gòu)
etcd 整體架構(gòu)圖如下:
2.1 客戶端層
包括 clientv3 和 etcdctl 等客戶端。用戶通過(guò)命令行或者客戶端調(diào)用提供了 RESTful 風(fēng)格的 API,降低了 etcd 的使用復(fù)雜度。
除此之外,客戶端層的負(fù)載均衡(etcd V3.4 版本的客戶端默認(rèn)使用的是 Round-robin,即輪詢調(diào)度)和節(jié)點(diǎn)間故障轉(zhuǎn)移等特性,提升了 etcd 服務(wù)端的高可用性。需要注意的是,etcd V3.4 之前版本的客戶端存在負(fù)載均衡的 Bug,如果第一個(gè)節(jié)點(diǎn)出現(xiàn)異常,訪問(wèn)服務(wù)端時(shí)也可能會(huì)出現(xiàn)異常,建議進(jìn)行升級(jí)。
2.2 API 接口層
API 接口層提供了客戶端訪問(wèn)服務(wù)端的通信協(xié)議和接口定義,以及服務(wù)端節(jié)點(diǎn)之間相互通信的協(xié)議。
etcd 有 V3 和 V2 兩個(gè)版本。
etcd V3使用gRPC作為消息傳輸協(xié)議;etcd V2默認(rèn)使用HTTP/1.x協(xié)議。
對(duì)于不支持 gRPC 的客戶端語(yǔ)言,etcd 提供 JSON 的 grpc-gateway 。通過(guò) grpc-gateway 提供 RESTful代理,轉(zhuǎn)換 HTTP/JSON 請(qǐng)求為 gRPC 的 Protocol Buffer 格式的消息。
2.3 etcd Raft 層
負(fù)責(zé) Leader 選舉和日志復(fù)制等功能,除了與本節(jié)點(diǎn)的 etcd Server 通信之外,還與集群中的其他 etcd 節(jié)點(diǎn)進(jìn)行交互,實(shí)現(xiàn)分布式一致性數(shù)據(jù)同步的關(guān)鍵工作。
2.4 邏輯層
etcd 的業(yè)務(wù)邏輯層,包括鑒權(quán)、租約、KVServer、MVCC 和 Compactor 壓縮等核心功能特性。
2.5 etcd 存儲(chǔ)
實(shí)現(xiàn)了快照、預(yù)寫式日志 WAL(Write Ahead Log)。etcd V3 版本中,使用 BoltDB 來(lái)持久化存儲(chǔ)集群元數(shù)據(jù)和用戶寫入的數(shù)據(jù)。
3. 各個(gè)模塊之間的交互
下圖中展示了 etcd 處理一個(gè)客戶端請(qǐng)求涉及的模塊和流程。
從上至下依次為 客戶端 → API 接口層 → etcd Server → etcd raft 算法庫(kù)。我們根據(jù)請(qǐng)求處理的過(guò)程,將 etcd Server 和 etcd raft 算法庫(kù)單獨(dú)說(shuō)明。
3.1 etcd Server
接收客戶端的請(qǐng)求,在上述的 etcd 項(xiàng)目代碼中對(duì)應(yīng) etcdserver 包。請(qǐng)求到達(dá) etcd Server 之后,經(jīng)過(guò) KVServer 攔截,實(shí)現(xiàn)諸如日志、Metrics 監(jiān)控、請(qǐng)求校驗(yàn)等功能。
etcd Server 中的 raft 模塊,用于與 etcd-raft 庫(kù)進(jìn)行通信。
applierV3 模塊封裝了 etcd V3 版本的數(shù)據(jù)存儲(chǔ);WAL 用于寫數(shù)據(jù)日志,WAL 中保存了任期號(hào)、投票信息、已提交索引、提案內(nèi)容等,etcd 根據(jù) WAL 中的內(nèi)容在啟動(dòng)時(shí)恢復(fù),以此實(shí)現(xiàn)集群的數(shù)據(jù)一致性。
3.2 etcdraft
etcd 的 raft 庫(kù)。raftLog 用于管理 raft 協(xié)議中單個(gè)節(jié)點(diǎn)的日志,都處于內(nèi)存中。
raftLog 中還有兩種結(jié)構(gòu)體 unstable 和 storage,這兩種結(jié)構(gòu)體分別用于不同步驟的存儲(chǔ),區(qū)別如下
unsable中存儲(chǔ)不穩(wěn)定的數(shù)據(jù),表示還沒有commit;storage中都是已經(jīng)被commit了的數(shù)據(jù);
除此之外,raft 庫(kù)更重要的是負(fù)責(zé)與集群中的其他 etcd Server 進(jìn)行交互,實(shí)現(xiàn)分布式一致性。
3.3 交互細(xì)節(jié)
在上圖中,客戶端請(qǐng)求與 etcd 集群交互包括如下兩個(gè)步驟:
-
首先是寫數(shù)據(jù)到
etcd節(jié)點(diǎn)中; -
其次是當(dāng)前的
etcd節(jié)點(diǎn)與集群中的其他etcd節(jié)點(diǎn)之間進(jìn)行通信,確認(rèn)存儲(chǔ)數(shù)據(jù)成功之后回復(fù)客戶端;
請(qǐng)求流程可劃分為以下的子步驟:
-
客戶端通過(guò)負(fù)載均衡算法選擇一個(gè)
etcd節(jié)點(diǎn),發(fā)起gRPC調(diào)用; -
etcd Server收到客戶端請(qǐng)求; -
經(jīng)過(guò)
gRPC攔截、Quota校驗(yàn),Quota模塊用于校驗(yàn)etcd db文件大小是否超過(guò)了配額; -
接著
KVServer模塊將請(qǐng)求發(fā)送給本模塊中的raft,這里負(fù)責(zé)與etcd raft模塊進(jìn)行通信; -
發(fā)起一個(gè)提案,命令為
put foo bar,即使用put方法將foo更新為bar; -
在
raft中會(huì)將數(shù)據(jù)封裝成raft日志的形式提交給raft模塊; -
raft模塊會(huì)首先保存到raftLog的unstable存儲(chǔ)部分; -
raft模塊通過(guò)raft協(xié)議與集群中其他etcd節(jié)點(diǎn)進(jìn)行交互。
需要注意的是,在 raft 協(xié)議中寫入數(shù)據(jù)的 etcd 必定是 leader 節(jié)點(diǎn),如果客戶端提交數(shù)據(jù)到非 leader 節(jié)點(diǎn)時(shí),該節(jié)點(diǎn)需要將請(qǐng)求轉(zhuǎn)發(fā)到 etcd leader 節(jié)點(diǎn)處理。
響應(yīng)流程的步驟如下:
-
提案通過(guò)
RaftHTTP網(wǎng)絡(luò)模塊轉(zhuǎn)發(fā),集群中的其他節(jié)點(diǎn)接收到該提案; -
在收到提案之后,集群中其他節(jié)點(diǎn)向
leader節(jié)點(diǎn)應(yīng)答“我已經(jīng)接收這條日志數(shù)據(jù)”; -
Leader收到應(yīng)答之后,統(tǒng)計(jì)應(yīng)答的數(shù)量,當(dāng)滿足超過(guò)集群半數(shù)以上節(jié)點(diǎn),應(yīng)答接收成功; -
etcd raft算法模塊構(gòu)造Ready結(jié)構(gòu)體,用來(lái)通知etcd Server模塊,該日志數(shù)據(jù)已經(jīng)被commit; -
etcd Server中的raft模塊(交互圖中有標(biāo)識(shí)),收到Ready消息后,會(huì)將這條日志數(shù)據(jù)寫入到WAL模塊中; -
正式通知
etcd Server該提案已經(jīng)被commit; -
etcd Server調(diào)用applierV3模塊,將日志寫入持久化存儲(chǔ)中; -
etcd Server應(yīng)答客戶端該數(shù)據(jù)寫入成功; -
etcd Server調(diào)用etcd raft庫(kù),將這條日志寫入到raftLog模塊中的storage;
上述過(guò)程中,提案經(jīng)過(guò)網(wǎng)絡(luò)轉(zhuǎn)發(fā),當(dāng)多數(shù) etcd 節(jié)點(diǎn)持久化日志數(shù)據(jù)成功并進(jìn)行應(yīng)答,提案的狀態(tài)會(huì)變成已提交。
在應(yīng)答某條日志數(shù)據(jù)是否已經(jīng) commit 時(shí),為什么 etcd raft 模塊首先寫入到 WAL 模塊中?
這是因?yàn)樵撨^(guò)程僅僅添加一條日志,一方面開銷小,速度會(huì)很快;另一方面,如果在后面 applierV3 寫入失敗,etcd 服務(wù)端在重啟的時(shí)候也可以根據(jù) WAL 模塊中的日志數(shù)據(jù)進(jìn)行恢復(fù)。etcd Server 從 raft 模塊獲取已提交的日志條目,由 applierV3 模塊通過(guò) MVCC 模塊執(zhí)行提案內(nèi)容,更新狀態(tài)機(jī)。
整個(gè)過(guò)程中,etcd raft 模塊中的 raftLog 數(shù)據(jù)在內(nèi)存中存儲(chǔ),在服務(wù)重啟后失效;客戶端請(qǐng)求的數(shù)據(jù)則被持久化保存到 WAL 和 applierV3 中,不會(huì)在重啟之后丟失。
參考:
https://kaiwu.lagou.com/course/courseInfo.htm?courseId=613#/detail/pc?id=6403
總結(jié)
以上是生活随笔為你收集整理的etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2022-2028年中国ITO薄膜行业市
- 下一篇: 2022-2028年中国硅酸钙板行业市场