跳到主要内容
跳到主要内容

表分片和副本


备注

此主题不适用于 ClickHouse Cloud,在这里,Parallel Replicas 类似于传统无共享 ClickHouse 集群中的多个分片,而对象存储则替代 副本,以确保高可用性和容错性。

ClickHouse 中的表分片是什么?

在传统的 shared-nothing ClickHouse 集群中,当 ① 数据对于单个服务器来说过大或 ② 单个服务器处理数据过慢时,会使用分片。下图展示了案例 ①,[uk_price_paid_simple](/parts) 表的数据超出了单台机器的容量:

SHARDS

在这种情况下,数据可以以表分片的形式分布在多个 ClickHouse 服务器上:

SHARDS

每个 ^^shard^^ 保留数据的一个子集,并作为一个常规的 ClickHouse 表独立查询。然而,查询只会处理该子集,这可能取决于数据分布的有效用例。通常,一个 distributed table(通常按服务器)提供对整个数据集的统一视图。它本身不存储数据,而是将 SELECT 查询转发给所有分片,汇总结果并将 INSERT 路由,以便均匀分配数据。

分布式表创建

为了说明 SELECT 查询转发和 INSERT 路由,我们考虑在两个 ClickHouse 服务器上分拆的 What are table parts 示例表。首先,我们展示创建相应的 ^^Distributed table^^ 的 DDL 语句:

CREATE TABLE uk.uk_price_paid_simple_dist ON CLUSTER test_cluster
(
    date Date,
    town LowCardinality(String),
    street LowCardinality(String),
    price UInt32
)
ENGINE = Distributed('test_cluster', 'uk', 'uk_price_paid_simple', rand())

ON CLUSTER 子句使 DDL 语句成为 distributed DDL statement,指示 ClickHouse 在 test_cluster 集群定义 列出的所有服务器上创建表。分布式 DDL 需要 Keeper 组件在 集群架构 中。

对于 distributed engine parameters,我们指定 ^^cluster^^ 名称(test_cluster)、目标分片表的数据库名称(uk)、目标分片表的名称(uk_price_paid_simple)和 sharding key 用于 INSERT 路由。在这个示例中,我们使用 rand 函数随机分配行到分片。然而,任何表达式——甚至复杂表达式——都可以用作分片键,这取决于用例。下一节将说明 INSERT 路由的工作原理。

INSERT 路由

下图展示了在 ClickHouse 中插入 ^^distributed table^^ 如何处理:

SHARDS

① 目标 ^^distributed table^^ 的 INSERT(单行)被发送到托管该表的 ClickHouse 服务器,可以直接发送或通过负载均衡器。

② 对于 INSERT 中的每一行(在我们的示例中只有一行),ClickHouse 评估分片键(这里是 rand()),并将结果对 ^^shard^^ 服务器的数量取模,并以此作为目标服务器 ID(ID 从 0 开始并增加 1)。然后,该行被转发并 ③ 插入到相应服务器的表 ^^shard^^ 中。

下一节将解释 SELECT 转发的工作原理。

SELECT 转发

下图展示了如何在 ClickHouse 中使用 ^^distributed table^^ 处理 SELECT 查询:

SHARDS

① 针对 ^^distributed table^^ 的 SELECT 聚合查询被发送到相应的 ClickHouse 服务器,可以直接发送或通过负载均衡器。

② ^^Distributed table^^ 将查询转发给所有托管目标表分片的服务器,每个 ClickHouse 服务器并行计算其本地聚合结果。

然后,托管最初目标的 ^^distributed table^^ 的 ClickHouse 服务器 ③ 收集所有本地结果, ④ 将它们合并为最终的全局结果,并 ⑤ 返回给查询发送方。

ClickHouse 中的表副本是什么?

ClickHouse 中的复制确保 数据完整性故障转移,通过在多台服务器上维护 ^^shard^^ 数据的副本。由于硬件故障是不可避免的,复制通过确保每个 ^^shard^^ 有多个副本来防止数据丢失。写入可以直接或通过 distributed table 定向到任何 ^^replica^^,该表选择用于该操作的 ^^replica^^。更改会自动传播到其他副本。遇到故障或维护时,数据仍然可以在其他副本上访问,一旦故障主机恢复,它会自动同步以保持更新。

请注意,复制在 集群架构 中需要一个 Keeper 组件。

下图展示了一个包含六台服务器的 ClickHouse ^^cluster^^,之前介绍的两个表分片 Shard-1Shard-2 每个都有三个副本。查询被发送到该 ^^cluster^^:

SHARDS

查询处理的工作方式与没有副本的设置相似,只有每个 ^^shard^^ 的单个 ^^replica^^ 执行查询。

副本不仅确保数据完整性和故障转移,还通过允许多个查询在不同副本上并行运行来提高查询处理吞吐量。

① 目标 ^^distributed table^^ 的查询被发送到相应的 ClickHouse 服务器,可以直接发送或通过负载均衡器。

② ^^Distributed table^^ 将查询转发给每个 ^^shard^^ 的一个 ^^replica^^,每个托管所选 ^^replica^^ 的 ClickHouse 服务器并行计算其本地查询结果。

其余部分的工作与没有副本的设置 相同,并在上图中未显示。托管最初目标的 ^^distributed table^^ 的 ClickHouse 服务器收集所有本地结果,将它们合并为最终的全局结果,并将结果返回给查询发送方。

请注意,ClickHouse 允许为 ② 配置查询转发策略。默认情况下——与上图不同——如果可用,^^distributed table^^ 更倾向于 本地 ^^replica^^,但可以使用其他负载均衡的 策略

哪里可以找到更多信息

有关表分片和副本的更多细节,除了这个高层次的介绍,请查看我们的 部署和扩展指南

我们还强烈推荐这个教程视频,以深入了解 ClickHouse 的分片和副本: