etcd架構
- client:提供了簡潔易用的API,同時支持負載均衡抛丽、節(jié)點故障自動轉移谤职,可極大降低業(yè)務使用etcd復雜度,提升開發(fā)效率、服務可用性亿鲜。
- API:client訪問etcd server的api,server之間訪問,節(jié)點間通過Raft算法實現(xiàn)數(shù)據復制和Leader選舉等功能允蜈。
- Raft算法層:實現(xiàn)Leader選舉、日志復制蒿柳、ReadIndex等核心算法特性,用于保證etcd多個節(jié)點間的數(shù)據一致性饶套、提供服務可用性等。
- 功能邏輯層: KVServer模塊垒探、MVCC模塊(treeIndex模塊和boltdb模塊)妓蛮、Auth鑒權模塊、Lease續(xù)約模塊圾叼、Comparator壓縮模塊蛤克。
- 存儲層:包含預寫日志(WAL)模塊(保證數(shù)據不丟)、快照模塊夷蚊、boltdb模塊(保存元數(shù)據和用戶數(shù)據)构挤。
etcd是典型的讀多寫少存儲。
Client
在etcd v3.4.9版本中,etcdctl是通過clientv3庫中訪問ectd server的, client v3庫基于gRPC client API封裝了操作etcd KVServer惕鼓、Cluster儿倒、
Auth、Lease、Watch等模塊的API夫否,同時包含了負載均衡彻犁、健康探測和故障切換等特性。
負載均衡算法:
- 如果client版本<=3.3,當配置多個endpoints時,負載均衡僅會從選擇一個IP并創(chuàng)建一個連接,這樣可以節(jié)省服務器總連接數(shù)凰慈。
在heavy usage場景,回造成server負載不均衡汞幢。- 在client 3.4 之前的版本中,負載均衡算法有一個嚴重bug:如果第一個節(jié)點異常了微谓,可能回導致client訪問etcd server異常,特別是
K8S 場景中會導致APIServer不可用森篷。在K8S 1.16版本后被修復。
KVServer
etcd通過攔截器提供了豐富的metrics豺型、日志仲智、請求行為檢查等機制,可記錄所有請求的執(zhí)行耗時及錯誤碼姻氨、來源IP等钓辆,也可控制請求是否允許通過。
etcd 實現(xiàn)了一些特性:
- 執(zhí)行一個操作前集群必須有Leader,防止腦裂;
- 請求延時超過指定閾值時,打印包含來源IP的慢查詢日志肴焊。
串行讀與線性讀
串行讀過程:
client發(fā)送請求到etcd server-->Leader 節(jié)點收到請求之后,持久化到WAL日志-->廣播給各個節(jié)點,等到一半以上節(jié)點上持久化成功-->將請求標記為已提交
-->ectd server 模塊異步從Raft模塊獲取已提交的日志條目,應用到狀態(tài)機前联。
線性讀是通過ReadIndex機制保證數(shù)據一致性原理。
線性讀過程:
KVServer模塊收到線性讀請求后,向Raft模塊發(fā)起ReadIndex請求,Raft模塊將Leader最新的已提交日志索引封裝在ReadState結構塊,通過channel
層層返回給線性讀模塊,線性讀模塊等待本節(jié)點狀態(tài)機追趕上Leader進度,追趕完成后,通知KVServer模塊,與狀態(tài)機中的MVCC模塊進行交互娶眷。
串行讀具有低延時似嗤、高吞吐量的特點,適合對數(shù)據一致性要求不高的場景。
線性讀解決讀數(shù)據一致性要求高的場景届宠。
MVCC
MVCC的核心由內存樹形索引模塊和嵌入式的KV持久化存儲庫boltdb組成烁落。
boltdb是基于B+ tree實現(xiàn)的k-v鍵值庫,支持事物,提供GET/PUT等簡易API給etcd操作。
etcd如何基于boltdb保存一個key的多個版本:
- 一個key保存多個歷史版本的值;導致value太大,存在明顯讀寫放大豌注、并發(fā)沖突等問題顽馋。
- 每次修改操作,生成一個新的新版本號;以版本號為key,value為用戶key-value等信息組成的結構體。
treeIndex
treeIndex是基于btree實現(xiàn)的幌羞。treeIndex模塊只會保存用戶的key和用戶版本號信息,用戶的key的value數(shù)據存儲在boltdb里面寸谜。
從treeIndex模塊中獲取hello這個key對應的版本號信息,treeIndex模塊基于B-tree快速查找此key, 返回此key對應的索引項keyIndex即可。
buffer
獲取版本號之后,可以從boltdb模塊中獲取用戶的key-value數(shù)據了属桦。在訪問boltdb前,首先會從一個內存讀事物buffer中熊痴,
二分查找要訪問key是否存在,如果命中則直接返回聂宾。
boltdb
boltdb是使用bucket隔離集群元數(shù)據和用戶數(shù)據,bucket就是MySQL的一個表,用戶的key數(shù)據存放真的bucket名字的是key,
etcd MVCC元數(shù)據存放的bucket是meta果善。