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

1. Citus是什麼

是PostgreSQL的擴展,能夠同PG一同安裝,以後經過SQL命令加入到數據庫中。html

【相關操做】node

?
1
2
#建立Citus擴展:
CREATE EXTENSION citus;

2. 節點

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

存儲全部的元數據,不存儲實際數據。爲應用系統提供服務,向各工做節點發送查詢請求,並彙總結果。對於應用系統而言是服務端,對於工做節點而言有點像客戶端。sql

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)

將同一張邏輯表中的數據按照必定策略,分別存儲到不一樣的物理表中去。物理表被稱爲分片。分片和工做節點是不一樣的概念,同一個工做節點上能夠放置許多的分片,甚至能夠將一張邏輯表分爲兩個分片,並將這兩個分片都存儲在同一個工做節點上。工具

分片原則性能

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

● 完備性:全部全局數據都要映射到某個片斷上。spa

● 可重構性:全部片斷必須能夠從新構成全局數據。設計

● 不相交性:劃分的個片斷所包含的數據無交集。

副本,即分片的冗餘。

【相關操做】

?
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系統同一分片的不一樣副本間的一致性。

相關文章
相關標籤/搜索