Clickhouse使用复制表时的集群架构如图所示:
此时同一个分片中的元数据会固化在zk中同一层父目录下,通过监听log队列,保证数据的一致性。
Clickhouse此时的分片规则---即集群架构,由用户来指定,具体放在metrika.xml配置文件中,而文章的核心---分布式表,就是由此来进行查询。
分布式表最常用的建表方式:
Create table XXX (略)
engine=Distributed(cluster,database,table,rand());
这里参数的含义分别是集群/库名/表名/分片选择策略(直接向分布式表写入时用到)。
分布式表实际上并不存储数据,而是表在集群层面上的一种逻辑上的聚合关系。以图中的例子,假设每个shard上都有一张表table A,每张表10条数据。此时查询基于整个集群shard的分布式表,求count(), 结果会是20。具体的查询逻辑(默认)为初始化节点向每个shard选择一个可用的节点,查到数据后汇总到初始化节点,进行最后的聚合。
这里是最基本也是最常用的场景,因为集群不会频繁的增减机器。
分布式表最重要的核心在于---集群结构。
下面分享三种特殊的场景的使用技巧:
1.集群扩容
集群扩容如何保证期间对用户透明是非常重要的。具体可以参照下列方式:
不要改动集群结构,先在新的集群上同步元数据(复制表/分布式表等),此时任意节点上查询的分布式表结果仍是旧集群的数据,不涉及新集群---这在双写场景会非常有用,同时即便元数据有问题,也不影响用户。
修改metrika,此时分布式表即对应集群所有分片。
2.监控集群信息
Clickhouse集群有个很特殊的地方:每个节点/分片的元数据是完全独立的,这就有元数据不一致的风险。
此时可以利用分布式表对所有节点的系统表进行监控
具体做法如下:
在metrika中新建一个cluster,指向所有的节点。
基于这个monitor cluster针对系统表创建分布式表,这样就能通过这张分布式表查看是否有元数据不一致,比如建表语句等。
3.巧用多个集群
有时资源紧张,不可能每个业务方专门搭建一个集群,此时可以控制用户只使用固定的某些shard。
具体做法如下:
创建一个只有部分节点的新集群(分片关系和之前的集群分片关系没有必然关系),针对这些特殊表创建基于这个集群的分布式表即可(在所有节点上创建)。