在當今信息爆炸的時代,單臺計算機已經沒法負載日益增加的業務發展,雖然也有性能強大的超級計算機,可是這種高端機不只費用高昂,也不靈活,通常的企業是負擔不起的,並且也損失不起,那麼將一羣廉價的普通計算機組合起來,讓它們協同工做就像一臺超級計算機同樣地對外提供服務,就成了順其天然的設想,可是這又增長了軟件的複雜度,要求開發的軟件須要具有橫向擴展能力,好比:Kafka、Elasticsearch、Zookeeper等就屬於這一類軟件,它們天生都是"分佈式的",便可以經過添加機器節點來共同地分攤數據存儲和負載壓力。html
分佈在不一樣區域的計算機,彼此之間經過網絡創建通訊,相互協做做爲一個總體對外提供服務,這就是集羣,若是咱們開發的系統具有這樣的能力,那麼理論上就具有無限橫向擴容的能力,系統的吞吐量就會隨着機器數增長而增加,那麼將來當系統出現高負載的時候,就能夠很好地應對這種狀況。node
經過上面分析,咱們知道實現集羣,其實就是採用多臺計算機來共同承擔和負載系統壓力,那麼就涉及到多臺計算機須要參與一塊兒處理數據,爲了保證可用性,通常都會在每臺計算機上備份一份數據,這樣只要有一個節點保持同步狀態,那麼數據就不會丟失,好比kafka分區多副本、Elasticsearch的副本分片,因爲同一數據塊及其副本位於不用的機器,隨着時間的推移,再加上不可靠的網絡通訊,全部機器上的數據必然會不徹底一致,這個時候假如發生一種極端狀況,全部的機器宕機了,又如何保證數據不丟失呢(其實只有兩種方法)?算法
其實當大多數機器不可用時,就須要在可用性和一致性之間進行妥協了,因此另外一個更符合分佈式系統的Base理論又被創造出來了。apache
當由多臺計算機組成的集羣對外提供服務時,其實就是對外提供讀、寫的能力。數組
爲了將數據合理、均勻地寫到各個機器上,提升集羣寫能力;爲了將讀請求負載均衡到不一樣的節點,提升集羣的讀能力;爲了解耦數據存儲和物理節點,提升分佈式讀寫並行處理的能力,聰明的工程師引入了一個邏輯數據存儲單位,統稱爲數據塊,好比Kafka的分區(partion)、Elasticsearch的分片(shard),這樣的虛擬化大大提升了集羣讀寫的靈活性。服務器
備註:因此啊,名字不重要,知其因此然最重要。網絡
實際上當集羣做爲一個總體處理數據時,可能每個節點都會收到讀寫請求,可是數據又是分散在不一樣的節點上,因此就須要每一個節點都清楚地知道集羣中任意一個數據塊的位置,而後再將請求轉發到相應的節點,這就是「協調節點」的工做。好比:Elasticsearch的master節點管理集羣範圍內的全部變動,主分片管理數據塊範圍內的全部變動。負載均衡
百度百科:quorum,翻譯法定人數,指舉行會議、經過議案、進行選舉或組織某種專門機構時,法律所規定的必要人數,未達法定人數無效。分佈式
因爲網絡分區的存在,這個機制被普遍地應用於分佈式系統中,好比集羣節點之間選舉Master;數據塊之間選舉Header等;在分佈式存儲中,也被稱爲Quorum讀寫機制,即寫入的時候,保證大多數節點都寫入成功(通常的作法會選舉一個主數據塊(header),保證它寫成功,而後再同步到冗餘的副本數據塊);讀取的時候保證讀取大多數節點的數據(通常的作法是由協調節點分發請求到不一樣的節點,而後將全部檢索到的數據進行全局彙總排序後再返回);因爲讀寫都是大多數,那麼中間確定存在最新的重疊數據,這樣就能保證必定能讀到最新的數據。性能
從上面分析能夠得出,只要大多數節點處於活躍可用狀態,那麼整個集羣的可用性就不會受到影響;只要大多數據塊處於活躍可用的狀態,那麼就能持續地提供讀寫服務;只要有一個數據塊完成了同步狀態,那麼數據就不會丟失;這其實就是經過一種冗餘機制來嘗試處理fail/recover模式的故障,通俗點講就是容忍單點故障,至少須要部署3個節點;容忍2點故障,至少須要部署5個節點,機器節點越多分區容忍性就越強,即經過增長機器數來下降因爲機器故障影響服務的機率,頓悟了吧,嘿嘿,因此保證集羣可用的前提就是有奇數個節點、奇數個數據塊保持活躍可用狀態,否則就沒法選舉出master或header。
大多數投票機制運用起來也很是靈活,當分佈式系統追求強一致性時,須要等待全部的數據快及其副本所有寫入成功纔算完成一次寫操做,即寫所有(write all),能夠理解一種事務保證,要麼所有寫入,要麼一個都不寫入,好比:kafka從0.11.0.0 版本開始, 當producer發送消息到多個topic partion時,就運用了這種機制,來保證消息交付的exactly-once語義,是否是很帥,並且這種狀況下,從任意一個節點都能讀到最新的數據,讀性能最高;當分佈式系統追求最終一致性時,只需等待主數據塊(leader)寫入成功便可,再由主數據塊經過消息可達的方式同步到副本數據塊。
爲了可以知足不一樣場景下對數據可靠性和系統吞吐量的要求,最大化數據持久性和系統可用性,不少組件都提供了配置項,容許用戶定義這個大多數的法定數量,下面咱們就來談談一些經常使用組件的配置:
Elasticsearch 由上圖能夠看到,整個集羣由三個運行了Elasticsearch實例的節點組成,有兩個主分片,每一個分片又有兩個副分片,總共有6個分片拷貝,Elasticsearch內部自動將相同的分片放到了不一樣的節點,很是合理和理想。 當咱們新建一個文檔時:
這就是Elasticsearch處理寫請求的典型步驟順序,同時每種業務場景對數據可靠性的要求和系統性能也不同,因此Elasticsearch提供了Consistence配置項:
Kafka 當向Kafka 寫數據時,producers能夠經過設置ack來自定義數據可靠性的級別:
備註:默認狀況下,爲了保證分區的最大可用性,當acks=all時,只要ISR集合中的副本分區寫入成功,kafka就會返回消息寫入成功。若是要真正地保證寫所有(write all),那麼咱們須要更改配置
transaction.state.log.min.isr
來指定topic最小的ISR集合大小,即設置ISR集合長度等於topic的分區數。
若是全部的節點都掛掉,還有Unclean leader選舉機制的保證,建議你們下去閱讀kafka《官方指南》設計部分,深刻理解kafka是如何經過引入ISR集合來變通大多數投票機制,從而更好地保證消息交付的不一樣語義。
對於分佈式系統,自動處理故障的關鍵就是可以精準地知道節點的存活狀態(alive)。有時候,節點不可用,不必定就是其自己掛掉了,極有多是暫時的網絡故障;在這種狀況下,若是立刻選舉一個master節點,那麼等到網絡通訊恢復正常的時候,豈不是同時存在兩個master,這種現象被形象地稱爲「集羣腦裂」,先留給你們下去思考吧。呵呵,明天要早起,碎覺了,你們晚安。
備註:設計一個正在高可用的分佈式系統,須要考慮的故障狀況每每會很複雜,大多數組件都只是處理了fail/recover模式的故障,即容忍一部分節點不可用,而後等待恢復;並無處理拜占庭故障(Byzantine),即節點間的信任問題,也許區塊鏈能夠解決吧,你們能夠下去多多研究,而後咱們一塊兒討論,共同窗習,一塊兒進步。
分享了這麼多,請你們總結一下大多數投票機制的優勢和缺點?歡迎評論區留言,哈哈,真的要睡覺了,晚安。
因爲昨晚太晚了,次日又要早起參加團建活動,對於最後就拋出的問題,但願你們下去總結一下大多數投票的優缺點,如今就來補充一下。
大多數投票機制延遲取決於最快的服務器,即等待數據備份完成的等待時間取決於最快的follower,好比副本因子是3,header佔據1位,再有1位最快的follower同步完成,就知足大多數了。
大多數(n+1)的節點掛掉就沒法選舉leader,從而整個集羣完全失去可用性,好比:爲了冗餘單點故障,一般須要三個節點備份數據,可是當其中兩臺掛掉時,整個集羣就掛了。僅僅靠冗餘數據來避免單點故障是不夠,一般對磁盤空間需求量爲2n+1倍,相應地也會致使寫吞吐量降低2n+1倍,這種高昂的存儲方式並不適合存儲原始數據,這就是爲何quorum算法更適合共享集羣配置數據,如zookeeper,這也是kafka爲何要引入一個同步狀態備份集合(ISR),經過下降所需的備份數據而帶來額外的吞吐量和磁盤空間,從而提升kafka處理海量實時數據的能力。