1. Citus是什麼
是PostgreSQL的擴展,可以同PG一同安裝,之後通過SQL命令加入到數據庫中。
【相關操作】
#創建Citus擴展:
CREATE EXTENSION citus;
2. 節點
2.1. 協調節點(coordinator node,簡稱CN)
存儲所有的元數據,不存儲實際數據。爲應用系統提供服務,向各工作節點發送查詢請求,並彙總結果。對於應用系統而言是服務端,對於工作節點而言有點像客戶端。
2.2. 工作節點(worker node,簡稱WN)
不存儲元數據,存儲實際數據。執行協調節點發來的查詢請求。原則上不直接爲應用系統提供服務。但是直接操作工作節點上的表也是可以實現的。
【相關操作】
#在協調節點上增加工作節點:
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)
將同一張邏輯表中的數據按照一定策略,分別存儲到不同的物理表中去。物理表被稱爲分片。分片和工作節點是不同的概念,同一個工作節點上可以放置許多的分片,甚至可以將一張邏輯表分爲兩個分片,並將這兩個分片都存儲在同一個工作節點上。
分片原則:
在設計分佈式數據庫的時候,設計者必須考慮數據如何分佈在各個場地上,也就是全局數據應該如何進行邏輯劃分和物理劃分。哪些數據應該分佈式存放,哪些不需要分佈式存放,哪些數據需要複製。對系統驚醒全盤考慮,使系統性能最優。但是無論如何進行分片都應該遵循以下原則:
- 完備性:所有全局數據都要映射到某個片段上。
- 可重構性:所有片段必須可以重新構成全局數據。
- 不相交性:劃分的個片段所包含的數據無交集。
副本,即分片的冗餘。
【相關操作】
#配置分片策略(在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. 分片修復
【相關操作】
#先查看分片分佈:
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的方法實現自動修復。
- 集羣性能
通過搭建基於PostgreSQL10的1CN+2WN的Citus集羣環境(兩分片,單副本)和單節點傳統PostgreSQL10進行對比的方法,採用PgBench測試工具的TPC-B模式,在記錄數100萬的情況下得出如下結果:TPS[Citus]=258,TPS[PG10]=688。即該配置下Citus集羣的整體讀寫效率爲傳統單節點PG10的37.5%。
通過合理的分片,使得大多數操作可以直接在WN進行,能有有效的提高Citus集羣的效率,但是在存在副本的情況下,需要應用程序人爲的保證Citus系統同一分片的不同副本間的一致性。
7.參考文獻
《分佈式數據庫的分片方法》
《在CentOS7.2上部署基於PostgreSQL10的citus分佈式數據庫》
《Citus初步測試》
《Citus性能測試》
《Citus數據分片分佈研究(一 在工作節點直接操作表)》
《Citus數據分片分佈研究(二 副本與故障)》
《Citus數據分片分佈研究(三 節點故障的手動修復)》
原文作者:皓月如我
原文鏈接:https://blog.csdn.net/fm0517/article/details/79577041