服务器主机配置:
CPU:单核2GHz
RAM:2GB
DISK:30GB HDD
Citus部署配置:
Coordinator X 1 (192.168.7.129)
Worker X 2 (192.168.7.130,192.168.7.131)
1.创建数据库,创建citus插件,部署citus扩展
在所有节点上:
psql -h 192.168.7.129/130/131 -p 5432 -U postgres
create extension citus;
在协调节点上:
psql -h 192.168.7.129 -p 5432 -U postgres
SELECT * from master_add_node('192.168.7.130', 5432);
SELECT * from master_add_node('192.168.7.131', 5432);
SELECT * FROM master_get_active_worker_nodes();
2.创建表,插入初始数据,查看分片分布
在协调节点上:
psql -h 192.168.7.129 -p 5432 -U postgres
#创建表
create table test_table(id int, name varchar(16));
#表分片
SELECT master_create_distributed_table('test_table', 'id', 'hash');
#设定分片个数(2)及每个分片副本数(2)
SELECT master_create_worker_shards('test_table', 2, 2);
#插入初始数据
INSERT INTO test_table VALUES(1,'a');
INSERT INTO test_table VALUES(2,'b');
INSERT INTO test_table VALUES(3,'c');
INSERT INTO test_table VALUES(4,'d');
--查看分片分布情况
SELECT * from pg_dist_shard_placement;
shardid | shardstate | shardlength | nodename | nodeport | placementid
---------+------------+-------------+---------------+----------+-------------
102010 | 1 | 0 | 192.168.7.130 | 5432 | 3
102011 | 1 | 0 | 192.168.7.130 | 5432 | 6
102010 | 1 | 0 | 192.168.7.131 | 5432 | 4
102011 | 1 | 0 | 192.168.7.131 | 5432 | 5
(4 rows)
一共有4个分片,分布在130和131两个工作节点上。
在工作节点上:
psql -h 192.168.7.130/131 -p 5432 -U postgres
\d
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+----------
public | test_table_102010 | table | postgres
public | test_table_102011 | table | postgres
(2 rows)
pgbench=# select * from test_table_102010;
id | name
----+------
1 | a
3 | c
4 | d
(3 rows)
pgbench=# select * from test_table_102011;
id | name
----+------
2 | b
(1 row)
这里通过查询可知,id=4的记录,经过哈希后,存储在编号为102010的分片上。(下一步实验会用到)
3.断开工作节点131后(拔网线),进行写操作,然后考察分片分布情况
在协调节点上查看数据及分片分布
select * from test_table;
WARNING: connection error: 192.168.7.131:5432
DETAIL: could not connect to server: No route to host
Is the server running on host "192.168.7.131" and accepting
TCP/IP connections on port 5432?
id | name
----+------
1 | a
3 | c
4 | d
2 | b
(4 rows)
SELECT * from pg_dist_shard_placement;
shardid | shardstate | shardlength | nodename | nodeport | placementid
---------+------------+-------------+---------------+----------+-------------
102010 | 1 | 0 | 192.168.7.130 | 5432 | 3
102011 | 1 | 0 | 192.168.7.130 | 5432 | 6
102010 | 1 | 0 | 192.168.7.131 | 5432 | 4
102011 | 1 | 0 | 192.168.7.131 | 5432 | 5
(4 rows)
在对表test_table进行数据查询的时候,出现了节点不可达的警告,但是因为没有写操作,所以所有分片分布状态仍然是正常的(同步的)。
插入id=4的记录
INSERT INTO test_table VALUES(4,'99');
WARNING: connection error: 192.168.7.131:5432
DETAIL: could not send data to server: No route to host
could not send SSL negotiation packet: No route to host
INSERT 0 1
根据前面的分析,这条记录应该被哈希到编号为102010的分片上。但此时节点131已经离线,所以只能写到节点位于130的102010号分片。此时再进行分片分布查询,发现节点131上的102010号分片状态从1变成了3,据此推断1表示“同步”,3表示“失步”。
SELECT * from pg_dist_shard_placement;
shardid | shardstate | shardlength | nodename | nodeport | placementid
---------+------------+-------------+---------------+----------+-------------
102010 | 1 | 0 | 192.168.7.130 | 5432 | 3
102011 | 1 | 0 | 192.168.7.130 | 5432 | 6
102010 | 3 | 0 | 192.168.7.131 | 5432 | 4
102011 | 1 | 0 | 192.168.7.131 | 5432 | 5
(4 rows)
4.故障修复
此时接上节点131的网线,再次查询分片分布,发现citus不能自动修复故障节点上的数据。
SELECT * from pg_dist_shard_placement;
shardid | shardstate | shardlength | nodename | nodeport | placementid
---------+------------+-------------+---------------+----------+-------------
102010 | 1 | 0 | 192.168.7.130 | 5432 | 3
102011 | 1 | 0 | 192.168.7.130 | 5432 | 6
102010 | 3 | 0 | 192.168.7.131 | 5432 | 4
102011 | 1 | 0 | 192.168.7.131 | 5432 | 5
(4 rows)
于是,使用master_copy_shard_placement命令将好节点上的分片,复制到坏节点上。
SELECT master_copy_shard_placement(102010, '192.168.7.130', 5432, '192.168.7.131', 5432);
master_copy_shard_placement
-----------------------------
(1 row)
此时再进行分片分布查询,发现节点131上的分片102010状态已经恢复。
SELECT * from pg_dist_shard_placement;
shardid | shardstate | shardlength | nodename | nodeport | placementid
---------+------------+-------------+---------------+----------+-------------
102010 | 1 | 0 | 192.168.7.130 | 5432 | 3
102011 | 1 | 0 | 192.168.7.130 | 5432 | 6
102010 | 1 | 0 | 192.168.7.131 | 5432 | 4
102011 | 1 | 0 | 192.168.7.131 | 5432 | 5
(4 rows)
写在最后
分片的同步和失步是以分片(shard)而不是节点(node)进行管理的。在本例中,插回131的网线后,在不执行master_copy_shard_placement的情况下,插入id=1、3、4的记录(对应分片102010),只能写入到节点130中,因为节点131上的102010分片状态仍被标记为失步;但是如果插入id=2的记录(对应分片为102011),是能够正常写入到两个节点中去的。