1. 為什么要分區(qū)?
分區(qū)(partitions) 也被稱為 分片(sharding),通常采用對(duì)數(shù)據(jù)進(jìn)行分區(qū)的方式來增加系統(tǒng)的 可伸縮性,以此來面對(duì)非常大的數(shù)據(jù)集或非常高的吞吐量,避免出現(xiàn)熱點(diǎn)。
分區(qū)通常和復(fù)制結(jié)合使用,使得每個(gè)分區(qū)的副本存儲(chǔ)在多個(gè)節(jié)點(diǎn)上,保證數(shù)據(jù)副本的 高可用。如下圖所示,如果數(shù)據(jù)庫被分區(qū),每個(gè)分區(qū)都有一個(gè)主庫。不同分區(qū)的主庫可能在不同的節(jié)點(diǎn)上,每個(gè)節(jié)點(diǎn)可能是某些分區(qū)的主庫,同時(shí)是其他分區(qū)的從庫。

1.1 一致前綴讀
分區(qū)也會(huì)由于復(fù)制延遲而產(chǎn)生問題,我們先來看下圖中的例子,是Poons先生和Cake小姐的對(duì)話:

Poons先生先問: “How far into the future can you see, Mrs.Cake?”
Cake小姐回答說: “About ten seconds usually, Mr.Poons.”
正常情況下,這段對(duì)話是有因果關(guān)系的(先問后答)。但是對(duì)于觀察者,他看到的順序卻是先得到了答案,再看到了問題,這就是在分區(qū)數(shù)據(jù)庫中,因復(fù)制延遲而產(chǎn)生的特殊情況。
為了避免這種混亂,我們就需要保證 一致前綴讀:如果一系列寫入按某個(gè)順序發(fā)生,那么任何人讀取這些寫入時(shí),也會(huì)看見它們以同樣的順序出現(xiàn)。一種解決方案是,確保任何因果相關(guān)的寫入都在相同的分區(qū)。
2. 該怎么分區(qū)?
分區(qū)的目的是將數(shù)據(jù)和負(fù)載均勻的分布到各個(gè)節(jié)點(diǎn)上,理論上10個(gè)節(jié)點(diǎn)能夠處理10倍的數(shù)據(jù)量和10倍單節(jié)點(diǎn)的讀寫吞吐量。
但是如果分區(qū)不均,那么就會(huì)出現(xiàn)一些分區(qū)有更多的數(shù)據(jù)或讀寫,我們稱之為 偏斜,這會(huì)使得分區(qū)后并沒有得到很大的效率提升。在極端情況下,所有的負(fù)載如果都落在一個(gè)分區(qū),使得該分區(qū)負(fù)載過高,我們稱之為 熱點(diǎn)。
所以,為了避免偏斜和熱點(diǎn)的產(chǎn)生,以鍵值數(shù)據(jù)的分區(qū)為例,討論如何將數(shù)據(jù)分區(qū)做得妥當(dāng)。
2.1 根據(jù)鍵的范圍進(jìn)行分區(qū)
我們可以根據(jù)鍵值的范圍進(jìn)行分區(qū),比如說我們以26個(gè)英文字符劃分26個(gè)分區(qū),之后根據(jù)鍵值首字母對(duì)它們進(jìn)行分區(qū)。通常情況下,鍵值并不是均勻分布的,這會(huì)造成按照首字母分區(qū)之后,發(fā)生數(shù)據(jù)偏斜。為了均勻分配數(shù)據(jù),分區(qū)的邊界需要根據(jù)數(shù)據(jù)分區(qū)的實(shí)際情況再進(jìn)行調(diào)整。
2.2 散列分區(qū)
一個(gè)好的散列函數(shù)可以將數(shù)據(jù)均勻分布,避免發(fā)生偏斜。但是這也帶來了問題:我們沒有辦法再進(jìn)行高效的范圍查詢。
3. 熱點(diǎn)消除
避免熱點(diǎn)最簡單的方法是將數(shù)據(jù)記錄進(jìn)行散列分區(qū),記錄因此會(huì)在所有節(jié)點(diǎn)上平均分配。
但是它并不能完全避免熱點(diǎn)的產(chǎn)生,因?yàn)槿绻械淖x寫操作都是針對(duì)同一個(gè)鍵的話,那么所有的請(qǐng)求還是會(huì)被路由到同一個(gè)分區(qū)。比如說有一個(gè)百萬粉絲的博主發(fā)布動(dòng)態(tài),該動(dòng)態(tài)根據(jù)博主ID的鍵值進(jìn)行分區(qū),如果此時(shí)有大量的粉絲對(duì)該動(dòng)態(tài)進(jìn)行互動(dòng),那么哈希策略會(huì)把這些請(qǐng)求都路由到同一個(gè)分區(qū)進(jìn)行操作,發(fā)生熱點(diǎn)事件。
其實(shí),我們還可以在該熱點(diǎn)鍵上再進(jìn)行分區(qū),以避免熱點(diǎn):在主鍵的最后拼接隨機(jī)數(shù),兩位十進(jìn)制的隨機(jī)數(shù)就能把一個(gè)主鍵分成100個(gè)不同的主鍵,從而存儲(chǔ)在不同的分區(qū)中,這就完成了熱點(diǎn)消除。但是主鍵被分割后,任何讀取工作都必須在每次讀取時(shí)將所有的數(shù)據(jù)拉出去合并到一起再返回結(jié)果。
4. 分區(qū)再平衡
如果保存某分區(qū)數(shù)據(jù)的服務(wù)器故障,需要使用其他服務(wù)器接管或想將目前的服務(wù)器換成性能更好的服務(wù)器,那么就需要進(jìn)行 分區(qū)再平衡。
分區(qū)再平衡 是將負(fù)載從集群中的一個(gè)節(jié)點(diǎn)向另一個(gè)節(jié)點(diǎn)移動(dòng)的過程。執(zhí)行再平衡需要滿足以下要求:
再平衡期間,數(shù)據(jù)庫應(yīng)該繼續(xù)接受讀取和寫入
節(jié)點(diǎn)之間只移動(dòng)必須的數(shù)據(jù),以便快速再平衡,并減少網(wǎng)絡(luò)和磁盤的IO負(fù)載
再平衡之后,負(fù)載應(yīng)該在集群中的節(jié)點(diǎn)之間公平地共享
比較簡單的再平衡分區(qū)策略是選擇 固定數(shù)量的分區(qū),當(dāng)節(jié)點(diǎn)數(shù)量增加時(shí),可以從原節(jié)點(diǎn)中 竊取 一些分區(qū)(當(dāng)節(jié)點(diǎn)數(shù)量減少時(shí),則發(fā)生相反的情況),如下圖所示:

在這種配置中,分區(qū)的數(shù)量通常在數(shù)據(jù)庫第一次建立時(shí)確定,操作比較簡單,之后不會(huì)改變,因此你需要選擇足夠多的分區(qū)以適應(yīng)未來的增長。但是,每個(gè)分區(qū)也有管理開銷,所以選擇太大的數(shù)字會(huì)適得其反。
除此之外也可選擇 動(dòng)態(tài)分區(qū),根據(jù)配置的分區(qū)大小,當(dāng)超過該閾值時(shí),可以將該大分區(qū)分割成兩個(gè)小分區(qū),能夠使 分區(qū)數(shù)量適應(yīng)總數(shù)據(jù)量。在大型分區(qū)拆分后,可以將其中的一半轉(zhuǎn)移到另一個(gè)節(jié)點(diǎn)上,以平衡負(fù)載。
還有一種 根據(jù)節(jié)點(diǎn)數(shù)增加來進(jìn)行分區(qū) 的方法:每個(gè)節(jié)點(diǎn)上有固定的分區(qū)數(shù),當(dāng)節(jié)點(diǎn)增加時(shí),分區(qū)將變小,新增的節(jié)點(diǎn)會(huì)從原有節(jié)點(diǎn)的分區(qū)中隨機(jī)進(jìn)行拆分,最終這個(gè)新節(jié)點(diǎn)獲得公平的負(fù)載份額。
分區(qū)再平衡可以 手動(dòng)執(zhí)行 也可以 自動(dòng)執(zhí)行。自動(dòng)再平衡比較方便,因?yàn)椴恍枰斯ぞS護(hù),但是它的執(zhí)行過程是不可預(yù)測的:再平衡時(shí)將大量數(shù)據(jù)集從一個(gè)節(jié)點(diǎn)轉(zhuǎn)移到另一個(gè)節(jié)點(diǎn)的過程中可能會(huì)產(chǎn)生很大的網(wǎng)絡(luò)開銷,這會(huì)使得該服務(wù)器對(duì)請(qǐng)求響應(yīng)的性能降低,對(duì)用戶的體驗(yàn)和生產(chǎn)造成負(fù)面影響。所以再平衡的過程有人參與是一件好事,這樣能防止發(fā)生運(yùn)維問題。
5. 請(qǐng)求路由(服務(wù)發(fā)現(xiàn))
當(dāng)我們已經(jīng)將數(shù)據(jù)進(jìn)行分區(qū)后,如何才能知道用戶想要的數(shù)據(jù)在哪個(gè)節(jié)點(diǎn)上?這可以概括為是一個(gè) 服務(wù)發(fā)現(xiàn) 的問題。為了解決這個(gè)問題,可以通過如下圖所示的三個(gè)方案

1. 允許訪問所有的節(jié)點(diǎn),如果第一個(gè)訪問的節(jié)點(diǎn)有該鍵值,則處理該請(qǐng)求,否則將該請(qǐng)求轉(zhuǎn)發(fā)到適當(dāng)?shù)墓?jié)點(diǎn)上,這個(gè)方法避免了使用注冊(cè)中心中間件,但是實(shí)現(xiàn)比較復(fù)雜
2. 使用分布式的協(xié)調(diào)服務(wù),用戶將所有的請(qǐng)求發(fā)送到路由層,由路由層將該請(qǐng)求轉(zhuǎn)發(fā)到合適的節(jié)點(diǎn)
3. 要求用戶(客戶端)自己知道分區(qū)和節(jié)點(diǎn)的分配
但是這其中還隱藏著一個(gè)問題:作出決策的組件(節(jié)點(diǎn)之一、路由層或客戶端)是如何了解數(shù)據(jù)在節(jié)點(diǎn)間的分配變化的?這就需要一個(gè)獨(dú)立的協(xié)調(diào)服務(wù),比如使用 zookeeper 來跟蹤元數(shù)據(jù),如下圖所示

每個(gè)節(jié)點(diǎn)都會(huì)在 zookeeper 中進(jìn)行注冊(cè),zookeeper 中維護(hù)有節(jié)點(diǎn)到各個(gè)分區(qū)的可靠映射,負(fù)責(zé)決策的組件在 zookeeper 中訂閱這個(gè)消息。當(dāng)分區(qū)分配發(fā)生改變時(shí),zookeeper 就會(huì)通知負(fù)責(zé)決策的組件更新路由信息,使其保持在最新的狀態(tài)。
除此之外也可以在各個(gè)節(jié)點(diǎn)間采用 流言協(xié)議 來傳播集群狀態(tài)的變化,這樣每個(gè)節(jié)點(diǎn)都維護(hù)有最新的數(shù)據(jù)路由方案,當(dāng)其中一個(gè)節(jié)點(diǎn)收到請(qǐng)求時(shí),會(huì)將其轉(zhuǎn)發(fā)到合適的分區(qū)節(jié)點(diǎn)上(對(duì)應(yīng)服務(wù)發(fā)現(xiàn)的方案一)。
-
節(jié)點(diǎn)
+關(guān)注
關(guān)注
0文章
229瀏覽量
25566 -
數(shù)據(jù)集
+關(guān)注
關(guān)注
4文章
1236瀏覽量
26188
發(fā)布評(píng)論請(qǐng)先 登錄
如何提高CYBT-243053-02吞吐量?
求助,關(guān)于使用iperf測量mesh節(jié)點(diǎn)吞吐量問題求解
網(wǎng)卡吞吐量測試解決方案
iperf固定吞吐量測試如何設(shè)置
USB CDC吞吐量問題
如何計(jì)算延遲和吞吐量?
防火墻的吞吐量
防火墻術(shù)語-吞吐量
debug 吞吐量的辦法
debug 吞吐量的辦法
如何顯著提高ATE電源吞吐量?
TMS320C6474通用總線架構(gòu)(CBA)吞吐量
用“分區(qū)”來面對(duì)超大數(shù)據(jù)集和超大吞吐量
評(píng)論