分散式系統-分割槽(partition)
分割槽(Partition
)
什麼是分割槽?
分割槽主要是為了可擴充套件性。不同的分割槽可以放在不共享叢集中的不同節點上
為什麼要分割槽?
- 提升系統的擴充套件性
- 提升系統的可用性(節點故障只會引起一部分資料丟失)
*水平分割槽與垂直分割槽
水平切分常用於分散式系統
- 不存在單庫資料量過大、高併發的效能瓶頸,提升系統穩定性和負載能力
- 應用端改造較小,不需要拆分業務模組
垂直切分常用於DBMS
- 解決業務系統層面的耦合,業務清晰
- 與微服務的治理類似,也能對不同業務的資料進行分級管理、維護、監控、擴充套件等
- 高併發場景下,垂直切分一定程度的提升IO、資料庫連線數、單機硬體資源的瓶頸
Synonymes(同義詞)
分割槽partition
在不同資料庫有不同的稱謂
-
Shard
[分片]MongoDB
,Elasticsearch
-
Region
[區域]HBase
-
tablet
[表塊]BigTable
-
vnode
[虛節點]Cassandra
,Riak
分割槽與複製
分割槽通常與複製結合使用,使得每個分割槽的副本儲存在多個節點上。 這意味著,即使每條記錄屬於一個分割槽,它仍然可以儲存在多個不同的節點上以獲得容錯能力。
鍵值資料的分割槽
分割槽目標是將資料和查詢負載均勻分佈在各個節點上。如果每個節點均勻分享資料和負載,那麼理論上10個節點應該能夠處理10倍的資料量和10倍的單個節點的讀寫吞吐量。
兩個概念 skew
&hot spot
-
skew
:一些分割槽比其他分割槽有更多的資料或查詢,我們稱之為偏斜 -
hot spot
:不均衡導致的高負載的分割槽被稱為熱點
根據鍵的範圍分割槽(Range Partitioning)
一種分割槽的方法是為每個分割槽指定一塊連續的鍵範圍(從最小值到最大值)
拿mysql range partition
為例,建立一個employees
表
CREATE TABLE employees (
id INT NOT NULL,fname VARCHAR(30),lname VARCHAR(30),hired DATE NOT NULL DEFAULT '1970-01-01' ,separated DATE NOT NULL DEFAULT '9999-12-31',job_code INT NOT NULL,store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
PARTITION p0 VALUES LESS THAN (6),PARTITION p1 VALUES LESS THAN (11),PARTITION p2 VALUES LESS THAN (16),PARTITION p3 VALUES LESS THAN (21)
);
複製程式碼
可以看到store_id
= 1~5被分到p0
分割槽,6-11被分到p2
分割槽,然後依次類推
range partition
的優缺點
- 支援範圍查詢,比如按照時間雜湊
load skew
根據鍵的雜湊分割槽
hash partition
雜湊雜湊
Map the (skewed) range of keys to a uniformly distributed range of hashes
一致性hash
上篇文章已經介紹過一致性hash
的內容了,不再贅述。
分片與次級索引
基於檔案的分割槽(document-based
)和基於關鍵詞(term-based
)的分割槽。
local index
Every partition manages its own index with all pointers to local data items
- Vertically(垂直) partitioned index
- Insert/update/delete: performed locally
- Select: queries all partition indexes
適用於OnLine Transaction Processing(聯機事務處理過程)
global index
Index entries are partitioned by their key independently from local data items
- Horizontally partitioned index
- Insert/update/delete: require remote updates
- Select: queries only one partition index
適用於OnLine Analytical Processing(分析處理過程)
分割槽再平衡
Things change:
- Query load → add more CPUs
- Data size → add more disks and RAM
- Nodes fail → other nodes need to take over
- Require to move data around (rebalancing)!
反面教材 hash mod N
如果n
改變了,那麼對於mod n
的數值也會隨著變更
比如:
123456 % 10 = 6,123456 % 11 = 3,123456 % 12 = 0,
固定數量的分割槽
如果一個節點被新增到叢集中,新節點可以從當前每個節點中竊取一些分割槽,直到分割槽再次公平分配
動態分割槽
- 建立一些初始分割槽數
- 如果分割槽超過某個最大大小閾值,將其拆分開來
- 如果分割槽小於最小的閾值,將其合併
類似於B
樹資料結構
按節點比例分割槽
請求路由
現在我們已經將資料集分割到多個機器上執行的多個節點上。但是仍然存在一個未解決的問題。當客戶端想要發出請求時,如何知道要連線哪個節點?隨著分割槽重新平衡,分割槽對節點的分配也發生變化。
這個問題可以概括為 服務發現(service discovery
)
- 迴圈策略的負載均衡(
Round-Robin Load Balancer
)如果節點恰好有請求的分割槽,則直接處理,否則轉發到適當的節點 - 首先將所有來自客戶端的請求傳送到路由層,它決定了應該處理請求的節點,並相應地轉
- 要求客戶端知道分割槽和節點的分配
許多分散式資料系統都依賴於一個獨立的協調服務,比如ZooKeeper
來跟蹤叢集元資料。每個節點在ZooKeeper
中註冊自己,ZooKeeper
維護分割槽到節點的可靠對映。
Cassandra
和Riak
採取不同的方法:他們在節點之間使用流言協議(gossip protocol
) 來傳播群集狀態的變化。請求可以傳送到任意節點,該節點會轉發到包含所請求的分割槽的適當節點