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

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

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

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

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

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