集中式OR分布式
如果Postgres数据库满足不了海量数据处理的需求,则可以考虑Citus。Citus是一款Postgres分布式插件,可以实现分布式数据库。对于是否使用分布式数据库,应该看实际的需求,不存在分布式数据库优于集中式数据库或者集中式数据库优于分布式数据库的说法,只能说在某些场景下,那一个更优的问题。
本文主要介绍分布式数据库的一些概念,后续会陆续介绍分布式查询以及分布式事务等。
分布式数据库介绍
节点类型
Citus存在两种节点,协调节点CoorDinator以及工作节点Workers。用户将查询发送给CoorDinator,CoorDinator接收到查询后,生成分布式执行计划,将任务分发Worker节点,Worker节点执行对应的计划,由CoorDinator汇集Worker节点的数据最终返回给用户。

表类型
Citus中存在3中表类型:
- Local Table : 与单机版表含义相同
- Distributed Table : 分布表,一般按某分布列将数据分布到不同的节点上
- Reference Table: 复制表,对每个节点都保存相同的表数据。适合小表。
对Reference Table,如果表比较小并且使用频率很高,建议使用Reference Table,可以降低对分布式表进行JOIN操作时进行重分布的代价。因为每个节点都有一份其拷贝,就不用进行重分布了。
对Distributed Table,适合非常大的表,按某个分布列进行分布,分布在多个节点上。一方面可以通过水平扩展,提升表数据存储能力,另一方面可以通过多个Worker节点并行执行,提高分析性查询的能力。
分布式表
在使用分布式数据库时,首先是创建分布式表,然后利用分布式查询引擎进行查询等操作。
我们先举个创建分布式表的用例:
创建分布式表示例一:
postgres@test=# create table mydist(a int, b int);
CREATE TABLE
postgres@test=# select create_distributed_table('mydist','a');
create_distributed_table
--------------------------
(1 row)
postgres@test=# select * from pg_dist_shard;
logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue
---------------+---------+--------------+---------------+---------------
mydist | 102092 | t | -2147483648 | -1073741825
mydist | 102093 | t | -1073741824 | -1
mydist | 102094 | t | 0 | 1073741823
mydist | 102095 | t | 1073741824 | 2147483647
(4 rows)
可以看到表mydist被分为4个Shard(分片),这个是通过citus.shard_count配置的,可以修改配置文件进行配置。
上面的语句发生了什么呢?先在协调节点建立表,再建立分布式表,在这个过程中会检查当前表是否可被分布(临时表等不支持创建分布式表),分布列是否合法,然后根据配置计算需要被分成多少Shard,协调节点会将分布式表元信息写入系统表中,并协调工作节点各自创建对应的Shard,期间通过分布式事务保证一致性,不会出现某个worker节点创建失败,而协调节点创建成功的情况。
对于工作节点中创建的Shard,可以认为是单节点上的表,命名方式为tablename_shardid。可以在工作节点查看到本工作节点有2个Shard表,可以正常的通过select * from mydist_102092查看分片的数据。
postgres@postgres=# \d
List of relations
Schema | Name | Type | Owner
------------+--------------------------------------+----------+----------
public | mydist_102092 | table | postgres
public | mydist_102094 | table | postgres
到这里你对分布式表是否有进一步的理解了呢。
创建分布式表示例二:
postgres@test=# create table replicated_table(a int, b int);
CREATE TABLE
postgres@test=# select create_reference_table('replicated_table');
create_reference_table
------------------------
(1 row)
Reference Table与Distributed Table不同,每个工作节点不对其进行分片,而是保存完整的表数据。同样也需要在协调节点保存元数据信息。
分布式事务
还有一个重要的问题,就是分布式事务,放到后续进行学习。




