Citus集群由Coordinator(CN节点)和Worker节点组成。CN节点上放元数据负责SQL分发; Worker节点上放实际的分片,各司其职。 可是,Citus里它们的功能也能够灵活的转换。html
1. Worker as CN
当一个普通的Worker上存储了元数据后,就有了CN节点分发SQL的能力,能够分担CN的负载。 这样的Worker按官方的说法,叫作Citus MX节点。node
配置Citus MX的前提条件为Citus的复制模式必须配置为streaming
。即不支持在多副本的HA部署架构下使用sql
citus.replication_model = streaming
而后将普通的Worker变成Citus MX节点架构
select start_metadata_sync_to_node('127.0.0.1',9002);
默认状况下,Citus MX节点上也会分配分片。官方的Citus MX架构中,Citus MX集群中全部Worker都是Citus MX节点。并发
若是咱们只想让少数几个Worker节点专门用于分担CN负载,那么这些节点上是不须要放分片的。 能够经过设置节点的shouldhaveshards属性进行控制。async
SELECT master_set_node_property('127.0.0.1', 9002, 'shouldhaveshards', false);
2. CN as Worker
Citus里CN节点也能够做为一个Worker加到集群里。ide
SELECT master_add_node('127.0.0.1', 9001, groupid => 0);
CN节点做为Worker后,参考表也会在CN上存一个副本,但默认分片是不会存在上面的。 若是但愿分片也在CN上分配,能够把CN的shouldhaveshards属性设置为true。函数
SELECT master_set_node_property('127.0.0.1', 9001, 'shouldhaveshards', true);
配置后Citus集群成员以下:高并发
postgres=# select * from pg_dist_node; nodeid | groupid | nodename | nodeport | noderack | hasmetadata | isactive | noderole | nodecluster | metadatasynced | shouldhaveshards --------+---------+-----------+----------+----------+-------------+----------+----------+-------------+----------------+------------------ 1 | 1 | 127.0.0.1 | 9001 | default | f | t | primary | default | f | t 3 | 0 | 127.0.0.1 | 9000 | default | t | t | primary | default | f | t 2 | 2 | 127.0.0.1 | 9002 | default | t | t | primary | default | t | f (3 rows)
把CN做为Worker用体现了Citus的灵活性,可是其适用于什么场景呢?post
官方文档的举的一个例子是,本地表和参考表能够Join。
这样的场景咱们确实有,那个系统的表设计是:明细表分片,维表做参考表,报表做为本地表。 报表之因此作成本地表,由于要支持高并发访问,可是又找不到合适的分布键让全部SQL都以路由方式执行。 报表作成参考表也不合适,副本太多,影响写入速度,存储成本也高。
那个系统用的Citus 7.4,还不支持这种用法。当时为了支持报表和参考表的Join,建了一套本地维表,经过触发器确保本地维表和参考维表同步。
3. 分片隐藏
在Citus MX节点(含做为Worker的CN节点)上,默认shard是隐藏的,即psql的'\d'看不到shard表,只能看到逻辑表。 Citus这么作,多是担忧有人误操做shard表。
若是想在Citus MX节点上查看有哪些shard以及shard上的索引。可使用下面的视图。
citus_shards_on_worker
citus_shard_indexes_on_worker
或者设置下面的参数
citus.override_table_visibility = false
4. Citus是怎么隐藏分片的?
Citus的plan hook(distributed_planner)中篡改了pg_table_is_visible
函数,将其替换成citus_table_is_visible
。 这个隐藏只对依赖pg_table_is_visible
函数的地方有效,好比psql的\d
。直接用SQL访问shard表是不受影响的。
static bool ReplaceTableVisibleFunctionWalker(Node *inputNode) { ... if (functionId == PgTableVisibleFuncId()) { ... functionToProcess->funcid = CitusTableVisibleFuncId(); ...
5. Citus多CN方案的限制和不足
- 不能和多副本同时使用
- Citus MX节点不能访问本地表
- 不能控制Citus MX节点上不部署参考表