Kubernetes之(三)核心組件ETCD介紹


Kubernetes之(三)核心組件ETCD介紹

Etcd是CoreOS基於Raft開發的分布式key-value存儲,可用於服務發現、共享配置以及一致性保障(如數據庫選主、分布式鎖等)。

ETCD的主要功能

  • 基本的key-value存儲
  • 監聽機制
  • key的過期及續約機制,用於監控和服務發現
  • 原子CAS和CAD,用於分布式鎖和leader選舉

ETCD基於RAFT的一致性

選舉方法

  • 初始化系統時,階段處於follower狀態並設定一個election timeout,如果在這時間周期內沒有收到來自leader的heartbeat,節點將發起選舉:將自己切換為candidate之后,向集群中其他follower節點發送請求,詢問其是否選舉自己成為leader。
  • 當收到來及集群中過半節點數的接受投票后,節點即成為leader,開始接受保存client的數據並向其他follower節點同步日志,如果沒有達成一致,則candidate隨機選擇一個等待時間(150-300ms)再次發起投票,得到集群中半數以上follower接受的candidate將成為lwader。
  • leader節點依靠定時向follower發送heartbeat來保持其地位。
  • 任何時候如果其他follower在election timeout期間都沒有收到來自leader的headerbeat,同樣會將自己狀態切換為candidate並發起選舉。沒成功選舉一次,新lwader的任期(Term)都會比之前的leader任期大1。

日志復制

當接Leader收到客戶端的日志(事務請求) 后先把該日志追加到本地的Log中,然后通過heartbeat把該Entry同步給其他Follower,Follower接收到日志后記錄日志然后向Leader發送ACK,當Leader收到大多數(n/2+1) Follower的ACK信息后將該日志設置為已提交並追加到本地磁盤中,通知客戶端並在下個heartbeat中Leader將通知所有的Follower將該日志存儲在自己的本地磁盤中。

安全性

安全性是用於保證每個節點都執行相同序列的安全機制,如當某個Follower在當前Leader commit Log時變得不可用了,稍后可能該Follower又會倍選舉為Leader,這時新Leader可能會用新的Log覆蓋先前已committed的Log,這就是導致節點執行不同序列;Safety就是用於保證選舉出來的Leader一定包含先前 commited Log的機制;

  • 選舉安全性(Election Safety) :每個任期(Term) 只能選舉出一個Leader
  • Leader完整性(Leader Completeness) :指Leader日志的完整性,當Log在任期Term1被Commit后,那么以后任期Term2、Term3…等的Leader必須包含該Log;Raft在選舉階段就使用Term的判斷用於保證完整性:當請求投票的該Candidate的Term較大或Term相同Index更大則投票,否則拒絕該請求。

失效處理

    1. Leader失效:其他沒有收到heartbeat的節點會發起新的選舉,而當Leader恢復后由於步進數小會自動成為follower(日志也會被新leader的日志覆蓋)
  • 2) follower節點不可用:follower 節點不可用的情況相對容易解決。因為集群中的日志內容始終是從 leader 節點同步的,只要這一節點再次加入集群時重新從 leader節點處復制日志即可。
  • 3) 多個candidate:沖突后candidate將隨機選擇一個等待間隔(150ms ~ 300ms)再次發起投票,得到集群中半數以上follower接受的candidate將成為leader

ETCD,Zoopkeeper,Consul比較

  • Etcd 和 Zookeeper 提供的能力非常相似,都是通用的一致性元信息存儲,都提供watch機制用於變更通知和分發,也都被分布式系統用來作為共享信息存儲,在軟件生態中所處的位置也幾乎是一樣的,可以互相替代的。二者除了實現細節,語言,一致性協議上的區別,最大的區別在周邊生態圈。Zookeeper 是apache下的,用java寫的,提供rpc接口,最早從hadoop項目中孵化出來,在分布式系統中得到廣泛使用(hadoop, solr, kafka, mesos 等) 。Etcd 是coreos公司旗下的開源產品,比較新,以其簡單好用的rest接口以及活躍的社區俘獲了一批用戶,在新的一些集群中得到使用(比如kubernetes) 。雖然v3為了性能也改成二進制rpc接口了,但其易用性上比 Zookeeper 還是好一些。
  • 而Consul 的目標則更為具體一些,Etcd 和 Zookeeper 提供的是分布式一致性存儲能力,具體的業務場景需要用戶自己實現,比如服務發現,比如配置變更。而Consul 則以服務發現和配置變更為主要目標,同時附帶了kv存儲。

ETCD實用注意事項

1、ETCD cluster初始化的問題

如果集群第一次初始化啟動的時候,有一台節點未啟動,通過v3的接口訪問的時候,會報告Error: Etcdserver: not capable 錯誤。這是為兼容性考慮,集群啟動時默認的API版本是2.3,只有當集群中的所有節點都加入了,確認所有節點都支持v3接口時,才提升集群版本到v3。這個只有第一次初始化集群的時候會遇到,如果集群已經初始化完畢,再掛掉節點,或者集群關閉重啟(關閉重啟的時候會從持久化數據中加載集群API版本) ,都不會有影響。

2、ETCD讀請求的機制

v2 quorum=true 的時候,讀取是通過raft進行的,通過cli請求,該參數默認為true。
v3 –consistency=“l” 的時候(默認) 通過raft讀取,否則讀取本地數據。sdk 代碼里則是通過是否打開:WithSerializable option 來控制。一致性讀取的情況下,每次讀取也需要走一次raft協議,能保證一致性,但性能有損失,如果出現網絡分區,集群的少數節點是不能提供一致性讀取的。但如果不設置該參數,則是直接從本地的store里讀取,這樣就損失了一致性。使用的時候需要注意根據應用場景設置這個參數,在一致性和可用性之間進行取舍。

3、ETCD的compact機制

Etcd 默認不會自動 compact,需要設置啟動參數,或者通過命令進行compact,如果變更頻繁建議設置,否則會導致空間和內存的浪費以及錯誤。Etcd v3 的默認的backend quota 2GB,如果不 compact,boltdb 文件大小超過這個限制后,就會報錯:”Error: etcdserver: mvcc: database space exceeded”,導致數據無法寫入。

ETCD的問題

當前 Etcd 的raft實現保證了多個節點數據之間的同步,但明顯的一個問題就是擴充節點不能解決容量問題。要想解決容量問題,只能進行分片,但分片后如何使用raft同步數據?只能實現一個 multiple group raft,每個分片的多個副本組成一個虛擬的raft group,通過raft實現數據同步。當前實現了multiple group raft的有 TiKV 和 Cockroachdb,但尚未一個獨立通用的。理論上來說,如果有了這套 multiple group raft,后面掛個持久化的kv就是一個分布式kv存儲,掛個內存kv就是分布式緩存,掛個lucene就是分布式搜索引擎。當然這只是理論上,要真實現復雜度還是不小。

參考文檔

Kubernetes指南-倪朋飛
Kubernetes-handbook-jimmysong-20181218


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM