pg_shard是一个PostgreSQL的sharding extension。可以用于Shards、Replicates tables和高可用。它可以在不修改Applications的情况下无缝分配(或叫做分发?)SQL。作为一个独立的extension,pg_shard适用与很多NOSQL的应用场景。
对一个pg_shard的Cluster来说,PG的各节点分为Master node和Worker node两类。Master node的主要用来存储metadata和作为所有查询的入口。
可以挑选Cluster中的任意一个PG node作为Master,其他节点作为Workers。
最简单的测试方法是在同一台主机上同时配置Master和Worker实例。在同一台主机配置时,每个PG实例运行在不同端口,可以简单的适用“localhost”作为Worker node的节点名称。一般,可以每台主机配置一个PG实例,这样更适合生产环境的复杂情况。这种配置情况下,需要配置这些PG实例可以相互通信。(主要是配置postgresql.conf的listen_address参数和pg_hba.conf文件)。无论怎样部署,Master都必须可以通过TCP无密码连接到Workder Node。
pg_shard的环境搭建
编译安装pg_shard
修改postgresql.conf文件的shared_preload_libraries=’pg_shard’
创建pg_shard的配置文件pg_worker_list.conf文件,格式如下:
# hostname port-number
worker-1 5432
worker-2 5433
需要重新启动Master node。
对Table进行分片的步骤
在Master节点上:
CREATE EXTENSION pg_shard;
SELECT master_create_distributed_table(‘table_name’,’partition_column’);
在Worker节点上:
SELECT master_create_worker_shards(‘table_name’,’shards_num’,’rep_num’);
一旦创建了shards,就可以在Cluster上进行查询了。目前,UPDATE和DELETE需要在WHERE条件子句中包含Partition Column。
pg_shard的管理工具
pgs_distrubution_metadata.partition;
pgs_distrubution_metadata.shard;
pgs_distrubution_metadata.shard_placement;
pg_shard的使用限制
1、不支持跨shard的事务
2、不支持除了partition key和foreign key的其他column上的唯一约束
3、不支持Distrubuted Join(但pg_shard的出品公司的CITUSDB是支持的,开源版本中不支持)
pg_shard不支持的语法
1、不支持修改表,如果要修改表,需要通过脚本在每个Worker上执行
2、DROP TABLE
3、INSERT INTO ...select...
目前不支持和不完善的技术点很多,不建议在生产使用。可以在应用场景比较单一、简单的地方用。例如:
tbl_example (id integer,val jsonb);
这样的表,来模拟类似mongodb的分片。
以下为功能点实际测试部分
---------------------------------------------------------------------------
目前仅测试了部分简单、常见的功能,红色粗体为不支持,红色非粗体为ERROR信息,供参考。
测试环境:master + 3个worker
对表进行shard:
sharddb=# SELECT master_create_distributed_table('customer_reviews', 'customer_id');
sharddb=# SELECT master_create_worker_shards('customer_reviews', 16, 2);
这时,在不同节点看到的表是不同的:
master: sharddb=# \d+ List of relations Schema | Name | Type | Owner | Size | Description -----{}---------------{}-------+---------- public | customer_reviews | table | postgres | 32 kB | (1 row) worker-1: sharddb=# \d+ List of relations Schema | Name | Type | Owner | Size | Description -----{}---------------------{}-------+---------- public | customer_reviews_10000 | table | postgres | 32 kB | ...... public | customer_reviews_10015 | table | postgres | 32 kB | (11 rows) worker-2: sharddb=# \d+ List of relations Schema | Name | Type | Owner | Size | Description -----{}---------------------{}-------+---------- public | customer_reviews_10000 | table | postgres | 32 kB | ...... public | customer_reviews_10015 | table | postgres | 32 kB | (11 rows) worker-3: sharddb=# \d+ List of relations Schema | Name | Type | Owner | Size | Description -----{}---------------------{}-------+---------- public | customer_reviews_10001 | table | postgres | 32 kB | ...... public | customer_reviews_10014 | table | postgres | 32 kB | (10 rows) |
在三个worker节点上,所分布的表是不同的,一共有16个表,按照两两保存副本的方式分别创建了表。