可擴(kuò)展性
還是從我們?yōu)槭裁葱枰植际较到y(tǒng)講起豺型。原因是我們要面對的數(shù)據(jù)量越來越大,從GB到TB再到現(xiàn)在的PB級买乃,單機(jī)無法勝任這樣的工作姻氨。
工作中也常有這樣的場景,隨著業(yè)務(wù)變得越來越復(fù)雜剪验,之前設(shè)計的系統(tǒng)無法處理日漸增長的負(fù)載肴焊。這時,我們就需要增加系統(tǒng)的容量功戚。
分布式系統(tǒng)的核心就是可擴(kuò)展性(Scalability)娶眷。
最基本而且最流行的增加系統(tǒng)容量的模型有兩種: 水平擴(kuò)展(Horizontal Scaling)和垂直擴(kuò)展(Vertical Scaling)。
所謂水平擴(kuò)展啸臀,就是指在現(xiàn)有的系統(tǒng)中增加新的機(jī)器節(jié)點届宠。垂直擴(kuò)展就是在不改變系統(tǒng)中機(jī)器數(shù)量的情況下,“升級”現(xiàn)有機(jī)器的性能乘粒,比如增加機(jī)器的內(nèi)存豌注。
舉個例子,假設(shè)你現(xiàn)在負(fù)責(zé)一批木材采伐的操作灯萍。你有3輛卡車轧铁,每輛車一次可以運(yùn)25根木材。那么1小時最多可以運(yùn)3輛卡車 * 25根木材 * 1小時=75根木材/小時旦棉。
如果要使這個系統(tǒng)的負(fù)荷量增加一倍齿风,用水平擴(kuò)展的辦法,我們可以將卡車的數(shù)量增加到6輛他爸;用垂直擴(kuò)展的辦法聂宾,我們可以使每輛卡車的運(yùn)輸量增加一倍果善,或者使每輛卡車的速度增加一倍诊笤。
你是不是已經(jīng)發(fā)現(xiàn)了,水平擴(kuò)展的適用范圍更廣巾陕,操作起來更簡單讨跟,并且會提升系統(tǒng)的可用性(Availability)。
如果你的系統(tǒng)部署在AWS或者其他主流的云服務(wù)上鄙煤,你只需要點幾個按鈕晾匠,就可以在現(xiàn)有的機(jī)器集群中增加一個新的節(jié)點。
但是梯刚,無節(jié)制地增加機(jī)器數(shù)量也會帶來一些問題凉馆,比如機(jī)器的管理、調(diào)度、通信會變得更加復(fù)雜澜共,出錯的可能性會更高向叉,更難保證數(shù)據(jù)的一致性等等。
與之相反嗦董,垂直擴(kuò)展并沒有讓整個系統(tǒng)變得更加復(fù)雜母谎,控制系統(tǒng)的代碼也不需要做任何調(diào)整,但是它受到的限制比較多京革。多數(shù)情況下奇唤,單個機(jī)器的性能提升是有限的。而且受制于摩爾定律匹摇,提高機(jī)器的性能往往比購買新的機(jī)器更加昂貴咬扇。
同樣地,在大數(shù)據(jù)的時代廊勃,數(shù)據(jù)增長速度越來越快冗栗,數(shù)據(jù)規(guī)模越來越大,對數(shù)據(jù)存儲系統(tǒng)的擴(kuò)展性要求也越來越高供搀。
傳統(tǒng)的關(guān)系型數(shù)據(jù)庫因為表與表之間的數(shù)據(jù)有關(guān)聯(lián)隅居,經(jīng)常要進(jìn)行Join操作,所有數(shù)據(jù)要存放在單機(jī)系統(tǒng)中葛虐,很難支持水平擴(kuò)展胎源。而NoSQL型的數(shù)據(jù)庫天生支持水平擴(kuò)展,所以這類存儲系統(tǒng)的應(yīng)用越來越廣屿脐,如BigTable涕蚤、MongoDB和Redis等。
一致性
可用性對于任何分布式系統(tǒng)都很重要的诵。一般來說万栅,構(gòu)成分布式系統(tǒng)的機(jī)器節(jié)點的可用性要低于系統(tǒng)的可用性。
舉個例子西疤,如果我們想要構(gòu)建一個可用性99.999%的分布式系統(tǒng)(每年約5分鐘的宕機(jī)時間)烦粒,但是我們使用的單臺機(jī)器節(jié)點的可用性是99.9%(每年約8個小時的宕機(jī)時間)。那么想要達(dá)到我們的目標(biāo)代赁,最簡單的辦法就是增加系統(tǒng)中機(jī)器節(jié)點的數(shù)量扰她。這樣即使有部分機(jī)器宕機(jī)了,其他的機(jī)器還在持續(xù)工作芭碍,所以整個系統(tǒng)的可用性就提高了徒役。
這種情況下,我們要思考一個問題:如何保證系統(tǒng)中不同的機(jī)器節(jié)點在同一時間窖壕,接收到和輸出的數(shù)據(jù)是一致的呢忧勿?這時就要引入一致性(Consistency)的概念杉女。
回到之前的例子,要保證分布式系統(tǒng)內(nèi)的機(jī)器節(jié)點有相同的信息鸳吸,就需要機(jī)器之間定期同步宠纯。
然而,發(fā)送信息也會有失敗的可能层释,比如信息丟失或者有的節(jié)點正好宕機(jī)而無法接收婆瓜。因此,一致性在高可用性的系統(tǒng)里是非常核心的概念贡羔。
接下來廉白,我會給你介紹幾個在工程中常用的一致性模型,分別是:強(qiáng)一致性(Strong Consistency)乖寒,弱一致性(Weak Consistency)猴蹂,最終一致性(Eventual Consistency)。
- 強(qiáng)一致性:系統(tǒng)中的某個數(shù)據(jù)被成功更新后楣嘁,后續(xù)任何對該數(shù)據(jù)的讀取操作都將得到更新后的值磅轻。所以在任意時刻,同一系統(tǒng)所有節(jié)點中的數(shù)據(jù)是一樣的逐虚。
- 弱一致性:系統(tǒng)中的某個數(shù)據(jù)被更新后聋溜,后續(xù)對該數(shù)據(jù)的讀取操作可能得到更新后的值,也可能是更改前的值叭爱。但經(jīng)過“不一致時間窗口”這段時間后撮躁,后續(xù)對該數(shù)據(jù)的讀取都是更新后的值。
- 最終一致性:是弱一致性的特殊形式买雾。存儲系統(tǒng)保證把曼,在沒有新的更新的條件下,最終所有的訪問都是最后更新的值漓穿。
上面這三點我描述得比較正式嗤军,但其實都不難理解。這里晃危,我進(jìn)一步給你做個說明叙赚。
在強(qiáng)一致性系統(tǒng)中,只要某個數(shù)據(jù)的值有更新山害,這個數(shù)據(jù)的副本都要進(jìn)行同步纠俭,以保證這個更新被傳播到所有備份數(shù)據(jù)庫中。在這個同步進(jìn)程結(jié)束之后浪慌,才允許服務(wù)器來讀取這個數(shù)據(jù)。
所以朴则,強(qiáng)一致性一般會犧牲一部分延遲性权纤,而且對于全局時鐘的要求很高钓简。舉個例子,Google Cloud的Cloud Spanner就是一款具備強(qiáng)一致性的全球分布式企業(yè)級數(shù)據(jù)庫服務(wù)汹想。
在最終一致性系統(tǒng)中外邓,我們無需等到數(shù)據(jù)更新被所有節(jié)點同步就可以讀取。盡管不同的進(jìn)程讀同一數(shù)據(jù)可能會讀到不同的結(jié)果古掏,但是最終所有的更新會被按時間順序同步到所有節(jié)點损话。所以,最終一致性系統(tǒng)支持異步讀取槽唾,它的延遲比較小丧枪。比如亞馬遜云服務(wù)的DynamoDB就支持最終一致的數(shù)據(jù)讀取。
除了以上三個庞萍,分布式系統(tǒng)理論中還有很多別的一致性模型拧烦,如順序一致性(Sequential Consistency),因果一致性(Casual Consistency)等钝计,如果你感興趣的話恋博,可以自己查資料了解一下。
在實際應(yīng)用系統(tǒng)中私恬,強(qiáng)一致性是很難實現(xiàn)的债沮,應(yīng)用最廣的是最終一致性。我們一起來看兩個例子本鸣。
很多人認(rèn)為銀行間轉(zhuǎn)賬應(yīng)該是強(qiáng)一致的秦士。但是你仔細(xì)分析一下就會發(fā)現(xiàn),事實并非如此永高。
舉個例子隧土,小王給小張轉(zhuǎn)賬1000元,小王的賬戶扣除了1000命爬,此時小張并不一定立刻就收到1000元曹傀。這里可能會存在一個不一致的時間窗口:小王的錢扣除了1000元,小張還沒收到1000元的時候饲宛。
另外一個例子皆愉,在12306網(wǎng)站買票的功能,也不是強(qiáng)一致的艇抠。
如果你在12306上發(fā)現(xiàn)一趟列車還剩余10張車票幕庐,你發(fā)起請求訂了一張票,系統(tǒng)給你返回的可能是“正在排隊家淤,剩余10張票异剥,現(xiàn)在有15人在購買”。
這時絮重,你可能就需要去查詢未完成訂單冤寿,因為系統(tǒng)并沒有給你及時返回訂票成功或失敗的結(jié)果歹苦。如果有人退了一張票,這張票也不會立即返回到票池中督怜。這里明顯也存在不一致的時間窗口殴瘦。
但是,最終10張票只會賣給10個人号杠,不可能賣給11個人蚪腋,這就是最終一致性所謂的“最終所有數(shù)據(jù)都會同步”。
講到這里姨蟋,你對分布式系統(tǒng)的擴(kuò)展性和一致性就很清楚了吧屉凯?接下來再給你介紹一個重要概念。
持久性
數(shù)據(jù)持久性(Data Durability)意味著數(shù)據(jù)一旦被成功存儲就可以一直繼續(xù)使用芬探,即使系統(tǒng)中的節(jié)點下線神得、宕機(jī)或數(shù)據(jù)損壞也是如此。
不同的分布式數(shù)據(jù)庫擁有不同級別的持久性偷仿。有些系統(tǒng)支持機(jī)器/節(jié)點級別的持久性哩簿,有些做到了集群級別,而有些系統(tǒng)壓根沒有持久性酝静。
想要提高持久性节榜,數(shù)據(jù)復(fù)制是較為通用的做法。因為把同一份數(shù)據(jù)存儲在不同的節(jié)點上别智,即使有節(jié)點無法連接宗苍,數(shù)據(jù)仍然可以被訪問。