來(lái)自Citus的Ozgun Erdogan分享了進(jìn)行數(shù)據(jù)庫(kù)分片的三個(gè)原則,并強(qiáng)調(diào)應(yīng)用類型是決定數(shù)據(jù)庫(kù)分片最主要的因素。其中B2B類型的應(yīng)用最容易進(jìn)行數(shù)據(jù)庫(kù)分片。
在數(shù)據(jù)庫(kù)很小的時(shí)候,可以很容易地通過(guò)添加硬件來(lái)擴(kuò)展數(shù)據(jù)庫(kù)。但隨著數(shù)據(jù)表數(shù)量的不斷增長(zhǎng),我們需要尋找其他的方式來(lái)伸縮數(shù)據(jù)庫(kù)。
分片是伸縮數(shù)據(jù)庫(kù)最好的方式之一。通過(guò)分片將數(shù)據(jù)庫(kù)拆分成更小的單元,可以線性地?cái)U(kuò)展數(shù)據(jù)庫(kù)的CPU、內(nèi)存和磁盤資源。不過(guò)在分片這個(gè)問(wèn)題上也存在一些爭(zhēng)議,網(wǎng)絡(luò)上充斥著各種有關(guān)分片的不同觀點(diǎn),如“essential to scaling your database infrastructure”和“why you never want to shard”。那么問(wèn)題來(lái)了,我們應(yīng)該采納哪一種觀點(diǎn)?而一般來(lái)說(shuō),答案通常會(huì)是“它取決于”。
分片的原理很簡(jiǎn)單,就是通過(guò)一個(gè)鍵(或者說(shuō)列)來(lái)均勻地分布數(shù)據(jù)。不過(guò)理論雖簡(jiǎn)單,在真正遇到要對(duì)數(shù)據(jù)庫(kù)進(jìn)行分片時(shí),很可能會(huì)陷入一團(tuán)手忙腳亂之中。
在Citus,我們?cè)?jīng)幫助數(shù)百個(gè)團(tuán)隊(duì)進(jìn)行數(shù)據(jù)庫(kù)分片,也從中總結(jié)了一些關(guān)鍵的分片模式。
在這篇文章里,我們會(huì)先探討一些決定分片成敗的關(guān)鍵屬性,然后從底層細(xì)節(jié)分析這些屬性之間的不同點(diǎn)。在進(jìn)行大型數(shù)據(jù)庫(kù)分片時(shí),應(yīng)用程序的類型將成為最主要的影響因素。
成功分片取決于三個(gè)關(guān)鍵屬性
我們發(fā)現(xiàn)有三個(gè)關(guān)鍵屬性會(huì)影響到成功的分片。下圖通過(guò)三個(gè)方向軸展示了這三個(gè)屬性,并在每個(gè)軸上面放置了一些知名的公司作為例子。
X-軸表示負(fù)載類型,從左側(cè)的事務(wù)開(kāi)始延伸到右側(cè)的數(shù)據(jù)倉(cāng)庫(kù)。在進(jìn)行數(shù)據(jù)庫(kù)伸縮時(shí),這一維度最具有識(shí)別度。
Z-軸表示另一個(gè)非常重要的屬性,也就是應(yīng)用程序當(dāng)前所處的生命周期。此時(shí)你的數(shù)據(jù)庫(kù)里有多少數(shù)據(jù)表?你的應(yīng)用程序已經(jīng)運(yùn)行了多長(zhǎng)時(shí)間?一個(gè)運(yùn)行了幾個(gè)月的數(shù)據(jù)庫(kù)要比運(yùn)行了數(shù)年的數(shù)據(jù)庫(kù)更容易進(jìn)行分片。
在Citus,我們發(fā)現(xiàn)大部分用戶都有自己的應(yīng)用程序。應(yīng)用程序越是成熟,Y-軸就顯得越為重要。不過(guò)這個(gè)維度不如其他兩個(gè)維度那么具有識(shí)別度。事實(shí)上,很多討論分片的文章之所以會(huì)得出互相矛盾的結(jié)論,是因?yàn)樗鼈冎皇腔趩我坏膽?yīng)用類型。
分片中最重要的屬性:應(yīng)用類型(B2B或B2C)
Y-軸展示了在對(duì)成熟數(shù)據(jù)庫(kù)進(jìn)行分片時(shí)最為重要的屬性:應(yīng)用程序的類型。在這條軸上,B2B應(yīng)用處于最上端,它們的數(shù)據(jù)模型更容易進(jìn)行分片。B2C應(yīng)用處于軸的底部,比如Amazon和Facebook,它們的分片需要做更多的工作。接下來(lái),我們挑選了三家知名的公司來(lái)比對(duì)它們之間的不同點(diǎn)。
B2B類型:Salesforce
CRM系統(tǒng)是B2B應(yīng)用最為典型的例子。構(gòu)建CRM系統(tǒng)的目的是為了要給其他客戶提供服務(wù)的,我們假設(shè)GE Aviation是你的一個(gè)客戶,他們正在使用Salesforce。
GE Aviation有如下的一些實(shí)體。
客戶(customer):公司的顧客。用戶(user):用戶可以登錄GE公司的儀表盤。負(fù)責(zé)人(lead):GE與這些負(fù)責(zé)人商談業(yè)務(wù)。聯(lián)系人(contact):GE與這些聯(lián)系人有了業(yè)務(wù)往來(lái),并知道他們的聯(lián)系方式。賬號(hào)(account):業(yè)務(wù)代表和擁有聯(lián)系人的人。機(jī)會(huì)(opportunity):與賬號(hào)和聯(lián)系人相關(guān)的銷售事件。如果把這些實(shí)體之間的復(fù)雜關(guān)系映射到數(shù)據(jù)庫(kù)里,看起來(lái)是這樣的:
整個(gè)圖咋一看確實(shí)很復(fù)雜,不過(guò)如果你多花一點(diǎn)時(shí)間看仔細(xì)一點(diǎn),你會(huì)發(fā)現(xiàn)大多數(shù)表都是源自customer表。通過(guò)往每個(gè)表里添加customer_id列可以把表間關(guān)系轉(zhuǎn)換成如下形式:
通過(guò)這種簡(jiǎn)單的轉(zhuǎn)換,就可以通過(guò)customer_id這個(gè)鍵進(jìn)行數(shù)據(jù)庫(kù)分片。這個(gè)鍵可以讓數(shù)據(jù)均勻地分布,而大部分查詢都需要帶上這個(gè)鍵。另外,你還可以根據(jù)customer_id把相關(guān)表聚集在同一個(gè)位置,這樣就可以繼續(xù)使用關(guān)系型數(shù)據(jù)庫(kù)的一些關(guān)鍵特性,比如事務(wù)、表連接和外鍵。
換句話說(shuō),如果你的應(yīng)用類型是B2B的,那么你的數(shù)據(jù)就具備了分片的天然特性。
B2C類型:Amazon
Amazon是B2C應(yīng)用最為典型的例子。在構(gòu)建像Amazon這樣的網(wǎng)站時(shí),有許多東西需要考慮。首先,用戶來(lái)到你的網(wǎng)站,瀏覽你的商品,比如書或電子產(chǎn)品。假設(shè)用戶在瀏覽《Harry Potter 7》,他們也可以看到這個(gè)產(chǎn)品的分類信息,比如書本的作者、價(jià)格、封面和其他圖片。
用戶在登錄網(wǎng)站之后,開(kāi)始訪問(wèn)用戶相關(guān)的數(shù)據(jù)。用戶需要得到認(rèn)證,然后獲得給產(chǎn)品添加評(píng)論的權(quán)限或者把產(chǎn)品添加到購(gòu)物車?yán)铩T谀硞€(gè)時(shí)候,用戶決定要購(gòu)買購(gòu)物車?yán)锏漠a(chǎn)品,于是就下單。訂單經(jīng)過(guò)處理之后,開(kāi)始進(jìn)入物流運(yùn)送流程。
你會(huì)發(fā)現(xiàn),現(xiàn)在的關(guān)系圖與Salesforce的關(guān)系圖有一個(gè)很大的不同點(diǎn)。現(xiàn)在的關(guān)系圖中不止一個(gè)中心點(diǎn),而是三個(gè):分類(catalog)、用戶(user)和訂單(order)。
要對(duì)這種B2C類型的數(shù)據(jù)進(jìn)行分片,可以考慮將它們重構(gòu)成微服務(wù)。例如,與產(chǎn)品目錄相關(guān)的服務(wù)提供目錄服務(wù),用戶相關(guān)的服務(wù)提供認(rèn)證和購(gòu)物車服務(wù)。服務(wù)之間的API定義了底層數(shù)據(jù)訪問(wèn)的邊界。
數(shù)據(jù)經(jīng)過(guò)拆分之后,就可以進(jìn)行分片。事實(shí)上,Amazon在遷移到面向服務(wù)架構(gòu)時(shí)就使用了類似的方式進(jìn)行數(shù)據(jù)分片。
這種分片方式與B2B應(yīng)用的分片在好處和成本比率上有很大的差別。從好處方面來(lái)看,你可以依賴數(shù)據(jù)庫(kù)從不同的數(shù)據(jù)庫(kù)連接數(shù)據(jù),或者為數(shù)據(jù)集提供事務(wù)和約束。從成本方面來(lái)看,現(xiàn)在要進(jìn)行分片的不止是一個(gè)數(shù)據(jù)集,而是多個(gè)。
B2C2C類型:Instacart
在B2B和B2C之間還有另外一種類型的網(wǎng)站,比如Postmates、Instacart或Lyft。[Instacart][12]的主營(yíng)業(yè)務(wù)是將本地商店的貨物運(yùn)送給用戶。從某方面來(lái)看,Instacart與Amazon有點(diǎn)類似。Instacart的數(shù)據(jù)模型具有三個(gè)維度:提供貨物的本地商店、訂購(gòu)商品的用戶和運(yùn)送貨物的司機(jī)。所以,很難在這當(dāng)中挑出一個(gè)鍵進(jìn)行分片。
如果你的應(yīng)用屬于B2C2C類型,可能需要采取不同的策略。你會(huì)發(fā)現(xiàn)大部分?jǐn)?shù)據(jù)表會(huì)共享一個(gè)維度:地理位置信息。在這種情況下,你可能會(huì)選擇城市或地理位置作為分片的鍵。
一般來(lái)說(shuō),B2B2C應(yīng)用或B2C2C應(yīng)用的分片處于圖譜的中間。B2B2C分片的好處和成本之間的比率要高于B2C應(yīng)用,但低于B2B應(yīng)用。
結(jié)論
網(wǎng)絡(luò)上存在很多有關(guān)分片的觀點(diǎn)。我們發(fā)現(xiàn)它們大部分都是基于單一的應(yīng)用類型。事實(shí)上,應(yīng)用類型比其他因素更能影響到分片。B2B類型的應(yīng)用最容易進(jìn)行分片。