Consul的使用一 之Consul的架構

Consul的架構

如下圖所示:

 

通常情況下, 一個數據中心由client和server組成, 並且需要保證server相對較少, 因爲server越多, server之間達成一致的速度越慢。

一個數據中心的所有agent都參與一個gossip協議。

Consul使用gossip協議來管理集羣中的成員關係, 廣播消息到集羣中。所有的這些都是通過Serf庫實現的, serf使用的gossip協議是SWIM(Scalable Weakly-consistent infection-style process group membership protocol).

 

client: 即以client模式啓動的consul客戶端, 通常情況下只是轉發請求到server, 並且佔用的資源極少。

server: 即以server模式啓動的consul客戶端。每個數據中心的所有server都是一個Raft peer set中的一員, 他們的職責通常包括選舉出一個leader, 這個leader負責處理所有請求和事務。 作爲一致性協議的一部分,事務會被轉發到peer set中的所有成員。當一個非leader的server接收到一個RPC請求時, 它會轉發請求到當前數據中心的leader。

 

Consul使用基於Paxos的Raft來提供一致性協議(consensus protocol),即CAP中的C。相比於Paxos, Raft擁有更少的狀態, 並且算法也更容易理解。

Raft中有幾個關鍵的概念:

Log : 在一個Raft系統中, 最基礎的工作單位就是一條log記錄。 因此一致性的問題也就成了log的一致性問題。 Log是有序的, 包含了集羣(cluster)中的所有的變化:添加節點, 添加服務, 增加key-value鍵值對等等。當所有的集羣成員都同意log中的記錄以及順序時, 這個log被認爲是一致的。

FSM: 無限狀態機, 一個無限狀態機就是有限狀態機的集合,並且包含了它們之間轉換的方法。當新的log被應用的時候, FSM被允許在狀態之間進行轉換。擁有相同順序的所有log的應用程序必然最終會到達同一個狀態。

Peer set: 一個peer set即使參與log備份的所有的成員。 從Consul的角度來說, 所有的server節點都參與到本地數據中心的peer set中。

Quorum: 一個quorum是一個peer set中的主要成員, 必須如果peer set大小爲n,則quorum要求至少(n/2)+1個成員。如果一個集羣中一個quorum數量的節點失敗, 則這個集羣就無法提供服務, 並且無法提交新的log。

Committed Entry: 當一個entry被持久化到一個quorum數量的節點上時, 這個log記錄被認爲是已提交, 並可以被應用到狀態機。

Leader: 在任何時間, 一個peer set中只有一個節點可以成爲leader, leader負責生成新的日誌記錄, 傳播到follower中, 並且決定何時一個記錄被認爲是已提交。

 

一個Raft節點總共有三個狀態:follower, candidate或者leader.

所有節點啓動時是follower狀態, 在這個狀態,節點可以接收leader的日誌記錄並且參與Leader選舉投票。當節點在一段時間沒有接收到Leader的日誌記錄時, 節點會自動進入candidate狀態。

在candidate狀態中, 節點要求peer set中的其他成員投票, 如果投票超過一個quorum數量, 則會成爲leader。

Leader必須接收新的日誌記錄並且傳播到其他的follower中。如果請求不接受過期的數據, 則所有的查詢請求必須由leader來響應。

 

Raft提供了一個機制, 可以快照保存當前的狀態並且壓縮日誌 , 這樣可以把保存的狀態之前的所有日誌移除到, 以節省空間, 這個是Raft自動完成的。Consul使用MemDB保存集羣的狀態, 而MemDB的一個優點就是可以在快照保存狀態機的狀態時依然接收新的事務。

 

 

Raft In Consul

剛開始時, 一個Consul server可以以"bootstrap"模式啓動, 這個模式可以允許server自選爲leader。 一旦leader確定, 其他的server就會加入到這個peer set中。

由於所有的節點都知道當前的Leader, 當RPC請求到達非leader server時,請求被轉發leader。

如果這個請求時查詢類型, 則leader基於狀態機當前的狀態生成結果;

如果這個請求時事務類型(transaction type), 意味着是更改狀態, 則leader生成一個新的log記錄, 並且通過Raft應用這條記錄。

 

一致性模式

所有的修改請求都會經過Raft形成日誌記錄, 但是讀請求卻有更多的選項。Consul支持3種讀一致性模式:

default: Raft通過leader租賃的方法, 保證在一個時間窗口內, leader的角色是不變的。

consistent: 強一致性模式, 每次都要向一個quorum數量的server確定它仍然是leader。

stale: 允許任何server響應讀請求。

 

Session

Consul提供了一個session的機制來構建分佈式鎖。 Session像是一個node, health checks以及key/value數據之間的綁定層, 提供精細的鎖。

 

 

在以下情況下, session會失效:

  • 節點註銷

  • 任何綁定的health check註銷

  • health check未通過

  • session被顯示銷燬

  • TTL過期

 

當session過期時, session上的鎖可能有兩種情況: 一是release, 這是默認行爲, 二是delete。Session必須在使用前創建, 然後引用它的ID。

Consul中的KV 接口被擴展成支持aquirerelease操作。aquirerelease均通過check-and-set的方式執行。獲取鎖成功, 則key的LockIndex增加, 當一個鎖釋放的時候,key對應的ModifyIndex增加。

 

Consul的安全模型

Consul依賴於一個輕量級的gossip以及一個RPC系統提供各種各樣的系統(RPC系統在0.8版本中被移除, 官方建議使用HTTP接口)。它們都有各自的安全機制。例如gossip協議使用對稱密鑰, 共享密鑰及密碼系統, RPC系統使用端對端加密來完成客戶端驗證。

這些安全機制都不是默認開啓的, 需要自己啓用。

推薦的安全機制:

ACL+默認拒絕:Consul配置成啓用ACL並且使用白名單方式, 默認拒絕。所有的請求必須有顯示的匿名token, 或者驗證的ACL token。

開啓加密: 開啓TCP和UDP加密, 從而使用agent之間的數據連接都是加密的。

 

參考:Consul的使用一 之Consul的架構

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章