1. 程式人生 > >[轉帖]PG裡面的Citus簡介----找時間學習一下.

[轉帖]PG裡面的Citus簡介----找時間學習一下.

1. Citus是什麼

是PostgreSQL的擴充套件,可以同PG一同安裝,之後通過SQL命令加入到資料庫中。

【相關操作】

?
1 2 #建立Citus擴充套件: CREATE EXTENSION citus;

2. 節點

2.1. 協調節點(coordinator node,簡稱CN)

儲存所有的元資料,不儲存實際資料。為應用系統提供服務,向各工作節點發送查詢請求,並彙總結果。對於應用系統而言是服務端,對於工作節點而言有點像客戶端。

2.2. 工作節點(worker node,簡稱WN)

不儲存元資料,儲存實際資料。執行協調節點發來的查詢請求。原則上不直接為應用系統提供服務。但是直接操作工作節點上的表也是可以實現的。

【相關操作】

?
1 2 3 4 5 6 7 8 9 10 11 #在協調節點上增加工作節點: SELECT * from master_add_node( '192.168.7.130' , 5432); SELECT * from master_add_node( '192.168.7.131' , 5432); SELECT
* from master_add_node( '192.168.7.132' , 5432); #檢視工作節點: SELECT * FROM master_get_active_worker_nodes(); node_name   | node_port ---------------+-----------   192.168.7.130 |      5432   192.168.7.131 |      5432   192.168.7.132 |      5432

3. 分片(shards)與副本(placement)

將同一張邏輯表中的資料按照一定策略,分別儲存到不同的物理表中去。物理表被稱為分片。分片和工作節點是不同的概念,同一個工作節點上可以放置許多的分片,甚至可以將一張邏輯表分為兩個分片,並將這兩個分片都儲存在同一個工作節點上。

分片原則

在設計分散式資料庫的時候,設計者必須考慮資料如何分佈在各個場地上,也就是全域性資料應該如何進行邏輯劃分和物理劃分。哪些資料應該分散式存放,哪些不需要分散式存放,哪些資料需要複製。對系統驚醒全盤考慮,使系統性能最優。但是無論如何進行分片都應該遵循以下原則:

● 完備性:所有全域性資料都要對映到某個片段上。

● 可重構性:所有片段必須可以重新構成全域性資料。

● 不相交性:劃分的個片段所包含的資料無交集。

副本,即分片的冗餘。

【相關操作】

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #配置分片策略(在CN上建立表之後): SELECT master_create_distributed_table( 'test_table' , 'id' , 'hash' ); #進行分片操作(將表分為3片,每個分片有2個副本): SELECT master_create_worker_shards( 'test_table' , 3, 2); #檢視分片: SELECT * from pg_dist_shard;   logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue --------------+---------+--------------+---------------+---------------   test_table   |  102001 | t            | -2147483648   | -1610612737   test_table   |  102002 | t            | -1610612736   | -1073741825   test_table   |  102003 | t            | -1073741824   | -536870913 #檢視分片分佈: SELECT * from pg_dist_shard_placement order by shardid, placementid;   shardid | shardstate | shardlength |   nodename    | nodeport | placementid ---------+------------+-------------+---------------+----------+-------------    102001 |          1 |           0 | 192.168.7.130 |     5432 |          33    102001 |          1 |           0 | 192.168.7.131 |     5432 |          34    102002 |          1 |           0 | 192.168.7.131 |     5432 |          35    102002 |          1 |           0 | 192.168.7.132 |     5432 |          36    102003 |          1 |           0 | 192.168.7.132 |     5432 |          37    102003 |          1 |           0 | 192.168.7.130 |     5432 |          38

從上面的分析可以看出,表test_table被分成了3個分片(102001,102002,102003),每個分片有2個副本,分別儲存在相鄰的兩個節點上。如下圖所示。

分片分佈表中shardstate為1時,表示當前副本的狀態是有效(同步)的;shardstate為3時,表示當前副本的狀態是有無效(失步)的。

4. 資料訪問

通過CN對錶test_table進行插入操作,根據先前定義的分片策略,citus會根據id的雜湊值自動為插入的記錄選擇一個分片進行寫入。

當WN3離線時,通過CN對錶test_table進行查詢操作,因為WN1和WN2上已經包含了所有的分片,所以查詢能夠正常返回應有的結果。此時檢視分片分佈,發現所有副本狀態都仍然為有效。

當WN3離線時,通過CN對錶test_table進行插入/更新/刪除操作,如果受影響的記錄屬於201001分片,那麼citus會修改WN1和WN2上test_table_102001表的資料,且不會對任何副本的狀態產生影響;如果受影響的記錄屬於201002分片,(因為WN3離線),citus會修改WN2上test_table_102002表的資料,並在分佈分片資訊中將36號副本的狀態置為“無效(失步)”,注意此時37號副本的狀態仍然是“有效(同步)”。

之後讓WN3重新上線,檢查分佈分片資訊,可以看到36號副本的狀態仍為“無效(失步)”,可見其不會自動修復。此時對201002分片的所有讀寫操作,都只對35號副本進行。

5. 分片修復

【相關操作】

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #先檢視分片分佈: SELECT * from pg_dist_shard_placement order by shardid, placementid;   shardid | shardstate | shardlength |   nodename    | nodeport | placementid ---------+------------+-------------+---------------+----------+-------------    102001 |          1 |           0 | 192.168.7.130 |     5432 |          33    102001 |          1 |           0 | 192.168.7.131 |     5432 |          34    102002 |          1 |           0 | 192.168.7.131 |     5432 |          35    102002 |          3 |           0 | 192.168.7.132 |     5432 |          36    102003 |          1 |           0 | 192.168.7.132 |     5432 |          37    102003 |          1 |           0 | 192.168.7.130 |     5432 |          38 #用35號副本的資料去覆蓋36號副本: SELECT master_copy_shard_placement(102002, '192.168.7.131' , 5432, '192.168.7.132' , 5432); #再次檢視分片分佈: SELECT * from pg_dist_shard_placement order by shardid, placementid;   shardid | shardstate | shardlength |   nodename    | nodeport | placementid ---------+------------+-------------+---------------+----------+-------------    102001 |          1 |           0 | 192.168.7.130 |     5432 |          33    102001 |          1 |           0 | 192.168.7.131 |     5432 |          34    102002 |          1 |           0 | 192.168.7.131 |     5432 |          35    102002 |          1 |           0 | 192.168.7.132 |     5432 |          36    102003 |          1 |           0 | 192.168.7.132 |     5432 |          37    102003 |          1 |           0 | 192.168.7.130 |     5432 |          38 #可見36號副本已經修復。

當且僅當分片時設定了副本數量大於1,且該分片目前存在有效副本時,才可以進行修復。從目前已知的情況來看,citus不能自動修復。可以通過開發守護程序檢測各個節點和副本的狀態,當發現出現失效副本時,在服務程式中呼叫master_copy_shard_placement的方法實現自動修復。

6. 叢集效能

通過搭建基於PostgreSQL10的1CN+2WN的Citus叢集環境(兩分片,單副本)和單節點傳統PostgreSQL10進行對比的方法,採用PgBench測試工具的TPC-B模式,在記錄數100萬的情況下得出如下結果:TPS[Citus]=258,TPS[PG10]=688。即該配置下Citus叢集的整體讀寫效率為傳統單節點PG10的37.5%。

通過合理的分片,使得大多數操作可以直接在WN進行,能有有效的提高Citus叢集的效率,但是在存在副本的情況下,需要應用程式人為的保證Citus系統同一分片的不同副本間的一致性。