本文講分佈式的共識概念,算法,應用。涉及到raft,paxos(basic,multi,fast),zk,etcd,chubby。以及思考。關注與如何共識,對於zk,etcd,chubby的接口如何應用於服務發現,分佈式鎖等略過。html
共識:一個或多個節點提出提案,算法選擇一個值。一致贊成,完整(只決定一次),有效(節點投票是有效值,是被提議的值),終止(宕機不回來)。
paxos徹底符合,但raft,zap考慮的是宕機還會回來的狀況,用日誌保證。能解決上篇(https://segmentfault.com/a/11...)中諸如如下問題:
全序廣播至關於重複多倫共識:raft和zap等直接實現全序廣播,mutil-paxos也是,都有leader,只決定值的順序。有固定leader比每一個節點寫入,leader維持全序,其餘節點同步,衝突少(若沒有leader paxos那種要先同步一遍獲取最大值,再投票,多了一次pre),畫一個有領導和無領導每一個帶序號的圖能夠很好理解帶leader會容易些,但單leader有瓶頸。
單領導類的共識:1選出一位領導者,2對領導者的提議進行表決(防止1,一個節點相信本身是領導)投票是同步的,動態成員擴展難,依靠超時檢測節點失效,若只有一條特定網絡不可靠,會進入領導頻繁二人轉局面。有領導後也不能領導決定,防止從新恢復等多領導定的狀況。
缺點:要多數都贊成,很慢。基本動態擴容很難,手動好比etcdnode
隨機的超時時間
。選term大,log長
的 2.leader會把本身的log複製到其餘機器,若是新達到多數而且此任期內已有數據過半(掛前的一次數據不會被重複提交)就提交,只提交新任期的,同步follower仍是要同步。
上面這個是https://www.microsoft.com/en-...。爲了方便理解,去除了實現細節。實時應用中,客戶端不會本身處理衝突+1再次投票和發送給其餘leaner,這些應該由另外一個角色,在basic中,由一羣c協調者,能夠和acceptor同樣,或者是其中的部分構成,每輪隨機一個c做爲leader,負責收集本輪結果和通知leaner。proposal->leader(每一個client隨機發就能夠做爲本輪leader)->pre->acceptors返回最大N的值V->帶N請求->acceptors->leader->返回給proposal->client失敗或者成功或再次投票->投票成功後發給leaner。此過程當中CLIENT2再次發送是另外一個leader。算法
若leader發現沒有衝突,再也不參與
,proposal直接提交給acceptor(同一輪只投給先到的),直接發送給leaner,能夠理解爲基於樂觀鎖的思想,leaner和CLIENT都自行決議,
chubby就是一個典型的Muti-Paxos算法應用,在Master穩定運行的狀況下,只須要使用同一個編號來依次執行每個Instance的Promise->Accept階段處理。數據庫
選主時每一個follower只能投一次
,不成功隨機時間下一次。有主時的共識由主來給日誌編號,follower比較就好,follower保證穩定可替換便可。zap在無主的時候選舉算法和fast paxos很像
,有最大xid(相似pre階段,只不過是上次存好的),先選主,每次選主的提案直接給acceptor而且採用無協調者的衝突處理。在有主時,用paxos的思想先pre收集並同步信息保證一致,主處理寫,多數處理成功後回覆。zk定位於分佈式協調服務
官方:https://zookeeper.apache.org/...
下面介紹zk的經常使用功能,架構,共識過程。apache
自己的數據組織以文件形式,每一個葉節點znodes,非頁節點只是命名空間的路徑標識;可是存儲於內存,記錄磁盤日誌,副本包含完整內存數據和日誌,znodes維護節點的版本,zxid等全部信息。 Zookeeper對於每一個節點QuorumPeer的設計至關的靈活,QuorumPeer主要包括四個組件:客戶端請求接收器(ServerCnxnFactory)、數據引擎(ZKDatabase)、選舉器(Election)、核心功能組件(Leader/Follower/Observer不一樣)
1.單獨zk集羣元數據的可靠性和一致性保證,元數據保存在zk全部副本中(少許徹底能夠放在內存中數據)
路由,選擇數據庫,調度程序
2.單獨zk集羣,鎖,防禦令牌,獲取鎖或者zxid
3.變動通知,每一個變動都會發送到全部節點
watch機制
4.用於檢測,服務發現
session:
每一個ZooKeeper客戶端的配置中都包括集合體中服務器的列表。在啓動時,客戶端會嘗試鏈接到列表中的一臺服務器。若是鏈接失敗,它會嘗試鏈接另外一臺服務器,以此類推,直到成功與一臺服務器創建鏈接或由於全部ZooKeeper服務器都不可用而失敗。
只要一個會話空閒超過必定時間,均可以經過客戶端發送ping請求(也稱爲心跳)保持會話不過時。ping請求由ZooKeeper的客戶端庫自動發送,所以在咱們的代碼中不須要考慮如何維護會話。這個時間長度的設置應當足夠低,以便能檔檢測出服務器故障(由讀超時體現),而且可以在會話超時的時間段內從新蓮接到另一臺服務器。segmentfault
採用了遞增的事務id號(zxid)來標識事務。全部的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識leader關係是否改變,每次一個leader被選出來,它都會有一個新的epoch,標識當前屬於那個leader的統治時期。低32位用於遞增計數。服務器
zab protocol網絡
Leader election leader選舉過程,electionEpoch自增,在選舉的時候lastProcessedZxid越大,越有可能成爲leader Discovery: 第一:leader收集follower的lastProcessedZxid,這個主要用來經過和leader的lastProcessedZxid對比來確認follower須要同步的數據範圍 第二:選舉出一個新的peerEpoch,主要用於防止舊的leader來進行提交操做(舊leader向follower發送命令的時候,follower發現zxid所在的peerEpoch比如今的小,則直接拒絕,防止出現不一致性) Synchronization: follower中的事務日誌和leader保持一致的過程,就是依據follower和leader之間的lastProcessedZxid進行,follower多的話則刪除掉多餘部分,follower少的話則補充,一旦對應不上則follower刪除掉對不上的zxid及其以後的部分而後再從leader同步該部分以後的數據 Broadcast 正常處理客戶端請求的過程。leader針對客戶端的事務請求,而後提出一個議案,發給全部的follower,一旦過半的follower回覆OK的話,leader就能夠將該議案進行提交了,向全部follower發送提交該議案的請求,leader同時返回OK響應給客戶端
實際上zookeeper中算法三階段:FSE=>Recovery=>Broadcast(廣播和上面的一致)session
fast leader election
基於fast paxos。發送給全部的節點。沒有隨機leader參與收集。
架構
LOOKING:進入leader選舉狀態 FOLLOWING:leader選舉結束,進入follower狀態 LEADING:leader選舉結束,進入leader狀態 OBSERVING:處於觀察者狀態 1.serverA首先將electionEpoch自增,而後爲本身投票 2 serverB接收到上述通知,而後進行投票PK 若是serverB收到的通知中的electionEpoch比本身的大,則serverB更新本身的electionEpoch爲serverA的electionEpoch 若是該serverB收到的通知中的electionEpoch比本身的小,則serverB向serverA發送一個通知,將serverB本身的投票以及electionEpoch發送給serverA,serverA收到後就會更新本身的electionEpoch 在electionEpoch達成一致後,就開始進行投票之間的pk,優先比較proposedEpoch,而後優先比較proposedZxid,最後優先比較proposedLeader pk完畢後,若是本機器投票被pk掉,則更新投票信息爲對方投票信息,同時從新發送該投票信息給全部的server。若是本機器投票沒有被pk掉,若是是looking,過半更改狀態,若是FOLLOWING/LEADING說明落後,加速收斂
常常應用於配置共享和服務發現,相比於zk,簡單。使用 Go 語言編寫部署簡單;使用 HTTP 做爲接口使用簡單;使用 `Raft 算法`保證強一致性讓用戶易於理解。無需安裝客戶端。提供接口K-V存儲(storing up to a few GB of data with consistent ordering,提供線性讀),watch,lease,lock,election。由於共識徹底實現的raft因此只簡單說下部署模式,節點組成,數據持久化等。 官方:https://coreos.com/etcd/docs/latest/
單節點以下
store:爲用戶提供API
集羣會區分proxy,leader,follower
GFS和Big Table等大型系統都用他來解決分佈式協做、元數據存儲和Master選擇等一系列與分佈式鎖服務相關的問題
客戶端發送到其餘機器都會將master反饋,從新轉到master,持續直到換。
數據組織方式和zk同樣。
只有主節點提供讀寫(數據和日誌有空洞),高可靠和可用,吞吐量不如zk。在換主階段會阻塞。
由於zk,etcd都會補齊follower。所以主從均可以讀。etcd的主是固定的,除非故障=》raft的換主。chubby(06年)用過的mutil-poxas主通常不變,不保證每輪主從數據一致,只有主有讀寫能力,吞吐量會差一些,一萬臺機器分佈式鎖仍是能夠的。etcd(14年)是後來的,確定更好啊,有http接口,一切都更輕量簡單,缺點只是無端障自恢復吧,zk每次都會選主(但基於一個xid,基本也相似mutil-poxas會穩定),可自動恢復。