ClickHouse 中的表分片是什么?
在这种情况下,可以将数据以表分片的形式分散到多台 ClickHouse 服务器上:
每个分片保存一部分数据,并作为可独立查询的常规 ClickHouse 表运行。不过,查询只会处理该分片上的那部分数据;根据数据分布情况,这在某些场景下也是合理的。通常会通过一个分布式表 (通常每台服务器一个) 来提供整个数据集的统一视图。它本身不存储数据,而是将 SELECT 查询转发到所有分片、汇总结果,并将 INSERTS 路由出去,以便将数据均匀分布到各个分片。
分布式表的创建
ON CLUSTER 子句会使该 DDL 语句成为分布式 DDL 语句,指示 ClickHouse 在 test_cluster 集群定义中列出的所有服务器上创建该表。分布式 DDL 还要求在集群架构中额外部署一个 Keeper 组件。
对于 Distributed 引擎参数,我们需要指定集群名称 (test_cluster) 、分片目标表所在的数据库名称 (uk) 、分片目标表的名称 (uk_price_paid_simple) ,以及用于 INSERT 路由的分片键。在本示例中,我们使用 rand 函数将行随机分配到各个分片。不过,分片键也可以是任意表达式——包括复杂表达式——具体取决于使用场景。下一节将说明 INSERT 路由的工作原理。
INSERT 路由
① 一个以分布式表为目标的 INSERT (包含单行数据) 会被发送到承载该表的 ClickHouse 服务器,可以直接发送,也可以通过负载均衡器发送。 ② 对于 INSERT 中的每一行 (本例中只有一行) ,ClickHouse 都会计算分片键 (此处为
rand()) ,将结果对分片服务器的数量取模,并将其作为目标服务器 ID (ID 从 0 开始,每次加 1) 。然后,该行会被转发,并在 ③ 对应服务器的表分片中插入。
下一节将说明 SELECT 转发的工作方式。
SELECT 转发
① 发往分布式表的 SELECT 聚合查询会被发送到相应的 ClickHouse 服务器,可以直接发送,也可以通过负载均衡器发送。 ② 分布式表会将该查询转发到所有托管目标表分片的 ClickHouse 服务器,在这些 ClickHouse 服务器 上,每个 ClickHouse 服务器 都会并行计算各自的本地聚合结果。 随后,最初接收该分布式表查询的 ClickHouse 服务器 会在 ③ 收集所有本地结果,④ 将其合并为最终的全局结果,并在 ⑤ 将结果返回给查询发送方。
ClickHouse 中的表副本是什么?
Shard-1 和 Shard-2 各自都有三个副本。一个查询被发送到该集群:
查询处理的方式与没有副本的配置类似,只是每个分片中只有一个副本会执行该查询。
副本不仅能确保数据完整性和故障转移,还能让多个查询在不同副本上并行运行,从而提升查询处理吞吐量。① 发往分布式表的查询会被发送到相应的 ClickHouse 服务器,可以直接发送,也可以通过负载均衡器发送。 ② 分布式表会将查询转发到每个分片中的一个副本,承载所选副本的每台 ClickHouse 服务器都会并行计算各自的本地查询结果。 其余部分与没有副本配置时相同,因此上图中未显示。承载最初目标分布式表的 ClickHouse 服务器会收集所有本地结果,将其合并为最终的全局结果,并将其返回给查询发送方。 请注意,ClickHouse 允许为步骤 ② 配置查询转发策略。默认情况下——与上图不同——分布式表会在可用时优先选择本地副本,但也可以使用其他负载均衡策略。