採用分佈式系統架構是由於業務需求決定的,若系統要求具備如下特性,便可考慮採用分佈式架構來實現:
1.數據存儲的分區容錯,冗餘
2.應用的大訪問、高性能要求
3.應用的高可用要求,故障轉移
分佈式系統遵循幾個基本原則
1.CAP原理
CAP Theorem,CAP原理中,有三個要素:
一致性(Consistency)
可用性(Availability)
分區容忍性(Partition tolerance)
CAP原理指的是,在分佈式系統中這三個要素最多隻能同時實現兩點,不可能三者兼顧。因此在進行分佈式架構設計時,必須做出取捨。而對於分佈式數據系統,分區容忍性是基本要求,否則就失去了價值。因此設計分佈式數據系統,就是在一致性和可用性之間取一個平衡。對於大多數web應用,其實並不需要強一致性,因此犧牲一致性而換取高可用性,是目前多數分佈式數據庫產品的方向。
從客戶端角度,多進程併發訪問時,更新過的數據在不同進程如何獲取的不同策略,決定了不同的一致性。對於關係型數據庫,要求更新過的數據能被後續的訪問都能看到,這是強一致性。如果能容忍後續的部分或者全部訪問不到,則是弱一致性。如果經過一段時間後要求能訪問到更新後的數據,則是最終一致性。
但web應用也有例外,比如支付寶系統,就要求數據(銀行賬戶)的強一致性,而且面對大量淘寶用戶,可用性要求很高,因此只能犧牲數據的分區冗餘。這一點也曾在和支付寶工程師交流時,得到驗證。
2.C10K問題
分佈式系統另一個理論是C10K問題,即系統的併發用戶增加1萬(customer ten thousand,過去一臺服務器承載假設爲1萬用戶,現在平均3~5萬),是否意味着增加一臺機器就能解決問題?答案通常是否定
因爲這涉及到系統的應用架構問題----串行系統和並行系統的架構和性能提升的關係:
串行系統一般設備越多,性能成一條向下彎曲的曲線,最差情況,可能性能不增反降;而並行分佈式系統設備越多,性能是正比例線性增長的直線
3.串行系統和並行系統的可靠性問題
一個大系統一般都有超過 30 個環節(串行):如果每個環節都做到 99% 的準確率,最終系統的準確率是 74%; 如果每個環節都做到98%的準確率,最終系統的準確率 54%。一個 74% 的系統是可用的(有商業價值的),一個 54% 的系統僅比隨機稍好一點,不可用。這就是做大系統的魅力和挑戰!
而以上描述只是各模塊串行系統所遇到的問題
如果是並行系統,準確率=1-(1-A)^B ,其中A是單個模塊準確率,B是並行模塊個數
如系統中每個模塊的準確率是70%,那麼3個模塊並行,整體準確率=1-0.3^3=97.3%,如果是4個並行,準確率=1-0.3^4=99.19%,我在想這就是負載均衡靠譜的數學原理
5個9或6個9的QoS一定是指數思維的結果,線性思維等於送死
而對系統單一模塊優化,準確性和可用性提升一個百分點,越接近100%,難度越大,投入成本越不可控(系統熵永不爲零)
因此可靠性系統必然選擇並行分佈式作爲架構的基本方法。
從數據的存儲角度,多份冗餘也是可靠性保障的一個方法。分佈式存儲的冗餘備份常規是3份(aws就這麼幹的),古埃及的羅塞塔rosetta石碑用古埃及象形文字、埃及拼音和古希臘文三種文字記錄一段歷史,就算象形文字缺了一部分,沒人能看懂,也能破譯補全,這大概也是raid5的思想起源吧
分佈式系統架構的實踐
1.分佈式存儲架構
分佈式存儲架構現階段有3種模式
1.1一種是物理存儲採用集中式,存儲節點採用多實例的方式,如NFS掛載SAN、NAS等等
1.2第二種是帶有中央控制器的分佈式存儲,如luster、moosefs、googlefs等等,一般特徵是具備2個角色metadata server和storage node,將文件的元數據(描述數據的數據,如文件位置、大小等等)和數據塊文件分開存儲
其中metadata server除保存文件的元數據外,還維護存儲節點的ip、狀態等信息
luster的典型架構
MDS--meatadata server
MDT--metadata target
OSS--obj storage server
OST--obj starage target
其中MDT和OST是可以掛在NAS等中央存儲上的;可見,luster借鑑了上面中央存儲的模式,無論元數據服務還是節點服務都將服務實例和存儲分離,但進化了一步,將元數據和數據塊分離
luster系統很好解決了數據分佈式存儲,,在超級計算領域Lustre應用廣泛,如美國LLNL國家實驗室計算機系統、我國的天河超級計算機系統均採用Lustre搭建分佈式存儲系統。Lustre在全球排名前30個超級計算機系統中有15個在使用。
但有一個問題,就是metadata server的SPoF(single point of failure)問題,即單點故障;一旦metadata server掛了,整個集羣也就掛了。實際應用中,是有解決方案的,如dell的官網有個pdf,就是採用heart beat和drbd網絡raid的方式,啓動2個實例,再如和keepalived一起組成故障轉移的方案等等,可以自己試試
再來看moosefs架構
moosefs架構和luster很相似,但進化了一步,mater(也就是metadata server)可以有從機備份了,而且可以多個
而且服務實例和存儲放在一起,沒有像luster,自此服務和數據不離不棄了;其實luster也可以簡化成不離不棄模式,moosefs也可以學他搞個後端存儲,但隨着雲計算、追求低成本的趨勢,採用SAN這樣存儲設備就太貴了
1.3第三種分佈式存儲是去中心化、全對稱的架構(non-center or symmetric)
其設計思想是採用一致性哈希consistent hash算法(DHT的一種實現,關於一致性hash具體參考後面的鏈接)來定位文件在存儲節點中的位置,從而取消了metadata server的角色
整個系統只有storage node一個角色,不區分元數據和數據塊;
典型系統如sheepdog,但sheepdog是爲滿足kvm鏡像和類EBS塊存儲而設計的,不是常規的分佈式文件系統,架構如下
爲了維護存儲節點的信息,一般採用P2P技術的totem single ring算法(corosync是一種實現)來維護和更新node路由信息
對稱架構有一個問題,採用totem single ring算法的存儲節點數量有限,因爲node數量超過1000,集羣內的通信風暴就會產生(此處更正,應該是環太大,令牌傳遞效率下降,不會產生通信風暴),效率下降,sheepdog提出了一個解決方案,就是在一致性hash環上做嵌套處理,如圖
1.4半對稱結構
其實介於1.2metadata server中央控制和1.3全對稱的架構之間還有一種,就是把metadata也做成對稱結構,我們可以稱半對稱結構,典型應用如fastdfs,淘寶一大牛fishman寫的,主要用作圖片存儲,可以實現排重存儲
看圖,tracker cluster就是metadata server的角色,實現了對稱架構設計
國內幾個大的網站都使用了fastdfs,在實際使用中,發現storage server之間同步數據較慢,一直沒仔細研究
2.分佈式數據庫
分佈式數據庫一般都基於分佈式文件系統實現數據的分片sharding,每中數據庫都有自己的應用特性,就不做介紹,列出幾個典型的應用,供參考
Google的big table,實現數據的追加存儲append,順序寫入快速,不適合隨機讀的場景
hadoop的HBase
mongodb
hypertable 2010年以前,百度在用,今年infoq的中國qcon,百度的楊棟也講了百度用hypertable的血淚史
3.分佈式應用架構
分佈式應用架構涉及具體應用場景,設計上除考慮上面的CAP和C10K等等經典分佈式理論,還應根據業務進行權衡。
基本的思路是
3.1在做完需求和模塊設計後,要對各模塊進行解藕Decoupling
傳統的企業應用設計一般是一條操作從頭跑到尾(串行系統),拿視頻網站的流程距離,傳統應用設計是先上傳是視頻,然後存儲,編碼,最後發佈一條龍
如下圖
3.2在進行分佈式設計時,先將各模塊解藕,通過異步消息通知的方式將各模塊鏈接,如下圖
3.3最後,要考慮這個應用的壓力承載點在哪,根據用戶規模估算各模塊的並行數量(如本例中的encode壓力大,就增加encode模塊的並行系統數量),如下圖
以上是分佈式系統構建的基本原則和實踐步驟,在實際應用中,仍有很多細節要考慮。但有一點要再強調,就是要根據業務來選擇各層、各模塊的技術,做好業務適用、成本和難度之間的權衡。
技術本無好壞,
參考:
moosefs http://www.moosefs.org
luster http://wiki.whamcloud.com/display/PUB/Wiki+Front+Page
一致性hash http://baike.baidu.com/view/1588037.htm & http://stblog.baidu-tech.com/?p=42
fastdfs http://code.google.com/p/fastdfs/wiki/Overview