Skip to main content
您可以将 S3 中的数据插入 ClickHouse,也可以将 S3 用作导出目标端,从而与“数据湖”架构进行交互。此外,S3 还能提供“冷”存储层级,并有助于实现存储与计算分离。在下面的章节中,我们将以纽约市出租车数据集为例,演示如何在 S3 和 ClickHouse 之间移动数据,同时介绍关键配置参数,并提供一些性能优化建议。

S3 表函数

s3 表函数允许你从兼容 S3 的存储中读取文件,也可以将文件写入其中。其语法结构如下:
其中:
  • path — 包含文件路径的 存储桶 URL。在只读模式下,支持以下路径通配符:*?{abc,def}{N..M},其中 NM 为数字,'abc''def' 为字符串。更多信息,请参阅在路径中使用通配符文档。
  • format — 文件的格式
  • structure — 表的结构。格式为 'column1_name column1_type, column2_name column2_type, ...'
  • compression — 该参数为可选。支持的值包括:nonegzip/gzbrotli/brxz/LZMAzstd/zst。默认情况下,会根据文件扩展名自动检测压缩方式。
在路径表达式中使用通配符可以引用多个文件,从而支持并行处理。

准备工作

在 ClickHouse 中创建表之前,你可能想先仔细查看一下 S3 存储桶中的数据。你可以直接在 ClickHouse 中使用 DESCRIBE 语句:
DESCRIBE TABLE 语句的输出应显示 ClickHouse 会如何自动推断 S3 存储桶中所见的数据。注意,它还会自动识别并解压 gzip 压缩格式:
为了与基于 S3 的数据集交互,我们准备了一个标准的 MergeTree 表作为目标端。下面的语句会在默认数据库中创建一个名为 trips 的表。请注意,我们选择对上文推断出的某些数据类型进行调整,尤其是不使用 Nullable() 数据类型修饰符,因为这可能会导致存储一些不必要的额外数据,并带来额外的性能开销:
请注意,这里在 pickup_date 字段上使用了分区。通常,分区键是用于数据管理的,但稍后我们会利用这个键将写入 S3 的操作并行化。 我们的出租车数据集中的每个条目都代表一次出租车行程。这些匿名化数据包含 2000 万条记录,压缩后存储在 S3 存储桶 https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi 文件夹下。数据采用 TSV 格式,每个文件约有 100 万行。

从 S3 读取数据

我们可以直接查询 S3 中的数据作为数据源,无需将其持久化到 ClickHouse 中。在下面的查询中,我们取 10 行样本。请注意,这里没有提供凭证,因为该存储桶可公开访问:
请注意,我们无需列出这些列,因为 TabSeparatedWithNames 格式会在第一行中包含列名。其他格式 (例如 CSVTSV) 则会为此查询返回自动生成的列,例如 c1c2c3 等。 查询还支持虚拟列,例如 _path_file,分别提供存储桶路径和文件名的信息。例如:
确认此样本数据集中的行数。注意这里使用了文件扩展通配符,因此会将全部 20 个文件都纳入统计。此查询大约需要 10 秒,具体取决于 ClickHouse 实例的 CPU 核心数:
虽然直接从 S3 读取数据很适合用于数据采样和执行临时的探索性查询,但这并不是你会想要经常做的事。到了需要认真处理的时候,就把数据导入 ClickHouse 中的 MergeTree 表。

使用 clickhouse-local

clickhouse-local 程序让你无需部署和配置 ClickHouse server,即可快速处理本地文件。任何使用 s3 表函数 的查询都可以通过该实用工具执行。例如:

从 S3 插入数据

为了充分发挥 ClickHouse 的全部能力,接下来我们会将数据读出并插入到实例中。 为此,我们将 s3 函数与简单的 INSERT 语句结合使用。请注意,我们无需列出各列,因为目标表已提供所需的结构。这要求各列按照表 DDL 语句中指定的顺序出现:系统会根据它们在 SELECT 子句中的位置进行映射。插入全部 1000 万行可能需要几分钟,具体取决于 ClickHouse 实例的性能。下面我们先插入 100 万行,以确保能快速返回结果。可根据需要调整 LIMIT 子句或列选择,以导入所需的子集:

使用 ClickHouse Local 进行远程插入

如果网络安全策略阻止您的 ClickHouse 集群发起出站连接,您仍可使用 clickhouse-local 将 S3 数据插入 ClickHouse。在下面的示例中,我们从 S3 存储桶读取数据,并使用 remote 函数将其插入 ClickHouse:
要通过安全的 SSL 连接执行此操作,请使用 remoteSecure 函数。

导出数据

你可以使用 s3 表函数将数据写入 S3 中的文件。这需要具备相应的权限。我们会在请求中传递所需的凭证,但如需了解更多选项,请参阅 管理凭证 页面。 在下面这个简单示例中,我们将表函数用作目标端而不是源端。这里,我们把 trips 表中的 10,000 行流式传输到一个存储桶,并指定 lz4 压缩和 CSV 输出类型:
请注意,这里文件的格式会根据扩展名自动推断。我们也不需要在 s3 函数中指定列,这也可以从 SELECT 中推断出来。

拆分大文件

你大概率不会想把数据导出成单个文件。大多数工具 (包括 ClickHouse) 在读写多个文件时,通常都能获得更高的吞吐量,因为这样可以并行处理。我们可以多次执行 INSERT 命令,每次处理一部分数据。ClickHouse 提供了通过 PARTITION 键自动拆分文件的方法。 在下面的示例中,我们使用 rand() 函数的模数创建了十个文件。注意,生成的分区 ID 会被引用到文件名中。这样会生成十个带数字后缀的文件,例如 trips_0.csv.lz4trips_1.csv.lz4 等:
或者,我们也可以直接引用数据中的某个字段。对于这个数据集,payment_type 是一个很自然的分区键,其基数为 5。

利用集群

上述函数都只能在单个节点上执行。读取速度会随 CPU 核心数线性提升,直到其他资源 (通常是网络) 达到饱和,从而实现纵向扩展。不过,这种方法也有其局限性。虽然在执行 INSERT INTO SELECT 查询时,可以通过插入到分布式表来缓解部分资源压力,但仍然只有一个节点负责读取、解析和处理数据。为了解决这一问题,并实现读取的横向扩展,我们提供了 s3Cluster 函数。 接收查询的节点称为发起节点,它会与集群中的每个节点建立连接。用于确定需要读取哪些文件的 glob 模式会被解析为一个文件集合。发起节点将文件分发给集群中的各个节点,这些节点充当工作节点。这些工作节点在完成读取后,会继续请求待处理的文件。通过这一过程,我们就能够对读取进行横向扩展。 s3Cluster 函数的格式与单节点变体相同,不同之处在于它需要指定目标集群,以标明工作节点:
  • cluster_name — 用于构建远程和本地服务器地址集合及连接参数的集群名称。
  • source — 指向单个文件或一组文件的 URL。在只读模式下支持以下通配符:*?{'abc','def'}{N..M},其中 N、M 为数字,abc、def 为字符串。更多信息请参见 路径中的通配符
  • access_key_idsecret_access_key — 指定用于给定端点的凭证密钥。可选。
  • format — 文件的 格式
  • structure — 表的结构。格式为 ‘column1_name column1_type, column2_name column2_type, …’。
与其他 s3 函数一样,如果存储桶本身不安全,或者你通过环境定义了安全机制 (例如 IAM 角色) ,则凭证是可选的。不过,与 s3 function 不同的是,自 22.3.1 起,必须在请求中指定结构,也就是说不会自动推断 schema。 在大多数情况下,此函数会作为 INSERT INTO SELECT 的一部分使用。在这种情况下,你通常插入的是一张分布式表。下面我们给出一个简单示例,其中 trips_all 是一张分布式表。虽然该表使用的是 events 集群,但读取和写入所使用节点的一致性并不是必需条件:
插入操作会在发起节点上执行。这意味着,虽然读取会在每个节点上进行,但生成的行会被路由到发起节点进行分发。在高吞吐量场景下,这可能会成为瓶颈。为解决此问题,请为 s3cluster 函数设置 parallel_distributed_insert_select 参数。

S3 表引擎

虽然 s3 函数支持对存储在 S3 中的数据执行临时查询,但其语法较为繁琐。使用 S3 表引擎后,你无需反复指定存储桶 URL 和凭证。为此,ClickHouse 提供了 S3 表引擎。
  • path — 存储桶 URL 及文件路径。在只读模式下支持以下通配符:*?{abc,def}{N..M},其中 N、M 表示数字,‘abc’、‘def’ 表示字符串。更多信息,请参见此处
  • format — 文件的格式
  • aws_access_key_id, aws_secret_access_key - AWS 账户用户的长期凭证。您可以使用它们对请求进行身份验证。该参数为可选。如果未指定凭证,则使用配置文件中的值。更多信息,请参见管理凭证
  • compression — 压缩类型。支持的值:none、gzip/gz、brotli/br、xz/LZMA、zstd/zst。该参数为可选。默认情况下,会根据文件扩展名自动检测压缩类型。

读取数据

在下面的示例中,我们使用 https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi/ 存储桶中的前 10 个 TSV 文件创建一个名为 trips_raw 的表。每个文件都包含 100 万行:
请注意,这里使用了 {0..9} 模式,将范围限制为前十个文件。创建后,我们可以像查询其他任何表一样查询这个表:

插入数据

S3 表引擎支持并行读取。仅当表定义中不包含 glob pattern 时,才支持写入。因此,上面的表无法写入。 为演示写入,请创建一个指向可写 S3 存储桶 的表:
请注意,只能向新文件中插入行。不存在合并周期或文件拆分操作。文件一旦写入,后续插入就会失败。这里用户有两个选项:
  • 指定设置 s3_create_new_file_on_insert=1。这会在每次插入时创建新文件。每个文件末尾都会追加一个数字后缀,并且会随着每次插入操作单调递增。对于上述示例,后续一次插入会创建一个 trips_1.bin 文件。
  • 指定设置 s3_truncate_on_insert=1。这会截断文件,也就是说,完成后文件将只包含新插入的行。
这两个设置的默认值均为 0,因此用户必须设置其中之一。如果两者都已设置,则 s3_truncate_on_insert 优先。 关于 S3 表引擎的一些说明:
  • 与传统的 MergeTree 家族表不同,删除 S3 表不会删除底层数据。
  • 此类表的完整设置可在此处查看。
  • 使用此引擎时,请注意以下限制:
    • 不支持 ALTER 查询
    • 不支持 SAMPLE 操作
    • 没有索引的概念,即主键索引或跳过索引。

管理凭证

在前面的示例中,我们在 s3 函数或 S3 表定义中直接传入了凭证。虽然对于偶尔使用,这种方式或许可以接受,但在生产环境中,用户通常需要不那么显式的身份验证机制。为此,ClickHouse 提供了多种选项:
  • config.xmlconf.d 下的等效配置文件中指定连接详情。下面展示了一个示例文件的内容,假设使用 debian 软件包安装。
    只要请求的 URL 与上述端点形成精确的前缀匹配,就会使用这些凭证。另请注意,此示例还支持声明 Authorization 请求头,作为 access key 和 secret key 的替代方案。支持的设置完整列表见此处
  • 上述示例还说明了配置参数 use_environment_credentials 可用。该配置参数也可以在 s3 级别进行全局设置:
    此设置会启用从环境中获取 S3 凭证的尝试,从而允许通过 IAM 角色进行访问。具体来说,将按以下顺序进行获取:
    • 查找环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN
    • 检查 $HOME/.aws
    • 通过 AWS Security Token Service 获取临时凭证,即通过 AssumeRole API
    • 检查 ECS 环境变量 AWS_CONTAINER_CREDENTIALS_RELATIVE_URIAWS_CONTAINER_CREDENTIALS_FULL_URI 以及 AWS_ECS_CONTAINER_AUTHORIZATION_TOKEN 中的凭证。
    • 通过 Amazon EC2 实例元数据获取凭证,前提是 AWS_EC2_METADATA_DISABLED 未设置为 true。
    • 也可以针对特定端点设置这些相同的参数,并使用相同的前缀匹配规则。

性能优化

有关如何使用 S3 函数优化读取和插入性能,请参阅专门的性能指南

S3 存储调优

在底层实现中,ClickHouse MergeTree 使用两种主要存储格式:Wide and Compact。当前实现仍采用 ClickHouse 的默认行为 (由设置 min_bytes_for_wide_partmin_rows_for_wide_part 控制) ,但我们预计在未来版本中,S3 的行为会有所不同。例如,增大 min_bytes_for_wide_part 的默认值会更倾向于使用 Compact 格式,从而减少文件数量。因此,如果你仅使用 S3 存储,现在可能就需要调优这些设置。

S3 后端的 MergeTree

s3 函数及其相关表引擎让我们可以使用熟悉的 ClickHouse 语法查询存储在 S3 中的数据。不过,它们在数据管理功能和性能方面存在一定局限:不支持主索引,不支持无缓存,文件插入也需要由用户自行管理。 ClickHouse 意识到,S3 是一种很有吸引力的存储解决方案,尤其是在对“较冷”数据的查询性能要求不那么高、且用户希望将存储与 compute 分离的场景下。为此,ClickHouse 提供了将 S3 用作 MergeTree 引擎存储后端的支持。这使你既能利用 S3 在可扩展性和成本方面的优势,又能获得 MergeTree 引擎的插入和查询性能。

存储分层

ClickHouse 存储卷将物理磁盘与 MergeTree 表引擎解耦。单个卷可以由一组按顺序排列的磁盘组成。这种抽象不仅可让多个块设备用于数据存储,还支持包括 S3 在内的其他存储类型。ClickHouse 数据分区片段可以根据存储策略和写满率在不同卷之间迁移,从而形成存储分层这一概念。 存储分层支持冷热分层架构:最新的数据通常也是查询最频繁的数据,因此只需在高性能存储 (例如 NVMe SSD) 上占用少量空间。随着数据逐渐老化,对查询时间的 SLA 要求会放宽,查询频率也会下降。这部分长尾数据可以存储在速度更慢、性能更低的介质上,例如 HDD 或 S3 这类对象存储。

创建磁盘

要将 S3 存储桶 用作磁盘,首先需要在 ClickHouse 配置文件中对其进行声明。你可以扩展 config.xml,更推荐的做法是在 conf.d 下新增一个文件。下面是一个 S3 磁盘声明示例:
与此磁盘声明相关的完整设置列表可在此处查看。请注意,此处的凭证也可通过管理凭证中所述的相同方式进行管理,即在上述设置块中将 use_environment_credentials 设为 true,以使用 IAM 角色。

创建存储策略

配置完成后,这个“磁盘”就可以供策略中声明的存储卷使用。在下面的示例中,我们假设 S3 是唯一的存储。这不涉及更复杂的冷热分层架构;在这类架构中,数据可根据生存时间 (TTL) 和写满率进行迁移。

创建表

假设你已将磁盘配置为使用具有写入权限的存储桶,那么你应该能够像下面的示例那样创建一个表。为简洁起见,我们仅使用 NYC taxi 的部分列,并将数据直接流式写入这个以 S3 为后端的表:
根据硬件配置的不同,后面这次插入 100 万行的数据可能需要几分钟才能完成。你可以通过 system.processes 表查看其进度。你也可以按需将行数增加到最多 1000 万行,并试试一些示例查询。

修改表

有时,你可能需要修改某个特定表的存储策略。虽然可以这样做,但有一些限制。新的目标策略必须包含原策略中的所有磁盘和卷,也就是说,数据不会为了满足策略变更而被迁移。在校验这些约束时,系统会根据名称识别卷和磁盘;如果尝试违反这些约束,就会报错。不过,如果你沿用前面的示例,则以下更改是有效的。
这里我们在新的 s3_tiered 策略中复用主卷,并引入一个新的 hot 卷。这里使用默认磁盘,它仅包含一个通过参数 <path> 配置的磁盘。请注意,我们的卷名和磁盘名称都不会改变。向表中插入的新数据会保留在默认磁盘上,直到达到 move_factor * disk_size,届时数据将被迁移到 S3。

实现复制

借助 ReplicatedMergeTree 表引擎,可在使用 S3 磁盘时实现复制。详情请参阅使用 S3 对象存储跨两个 AWS 区域复制单个分片指南。

读写

以下说明介绍了 ClickHouse 与 S3 交互的实现方式。虽然通常只是补充信息,但在性能优化时,可能会对读者有所帮助:
  • 默认情况下,查询处理管道中任一阶段可使用的最大查询处理线程数等于 CPU 核心数。某些阶段比其他阶段更容易并行化,因此该值只是一个上限。由于数据是从磁盘流式传输的,多个查询阶段可能会同时执行,因此单个查询实际使用的线程数可能会超过该值。可通过设置 max_threads 进行调整。
  • 默认情况下,从 S3 读取是异步进行的。此行为由设置 remote_filesystem_read_method 决定,其默认值为 threadpool。处理请求时,ClickHouse 会以 stripe 为单位读取粒度。每个 stripe 可能包含很多列。线程会逐个读取这些粒度中的列。与同步逐列读取不同,系统会先对所有列执行预取,然后再等待数据返回。相比对每一列都进行同步等待,这种方式能显著提升性能。大多数情况下,你无需更改此设置——请参见性能优化
  • 写入会并行执行,最多支持 100 个并发文件写入线程。max_insert_delayed_streams_for_parallel_write 的默认值为 1000,用于控制并行写入的 S3 blob 数量。由于每个正在写入的文件都需要一个缓冲区 (约 1MB) ,这实际上限制了 INSERT 的内存占用。在服务器内存较低的场景下,适当调低该值可能更合适。

将 S3 对象存储用作 ClickHouse 磁盘

如果您需要有关创建 S3 存储桶和 IAM 角色的分步说明,请参阅“如何创建 AWS IAM 用户和 S3 存储桶”

配置 ClickHouse 使用 S3 存储桶 作为磁盘

以下示例基于以服务形式安装的 Linux Deb 软件包,并使用 ClickHouse 的默认目录。
  1. 在 ClickHouse 的 config.d 目录中创建一个新文件,用于存放存储配置。
  1. 添加以下存储配置;将其中的 bucket 路径、access key 和 secret key 替换为前面步骤中的相应值
<disks> 标签中的 s3_disks3_cache 都是任意命名的标签。你可以改用其他名称,但在 <policies> 标签下的 <disk> 标签中引用该磁盘时,必须使用相同的标签名。 <S3_main> 标签同样是任意命名的,它表示策略名称,在 ClickHouse 中创建资源时将用作存储目标的标识符。上面显示的配置适用于 ClickHouse 22.8 或更高版本;如果你使用的是较早版本,请参阅存储数据文档。有关使用 S3 的更多信息: Integrations 指南:S3 Backed MergeTree
  1. 将文件所有者更新为 clickhouse 用户和组
  1. 重启 ClickHouse 实例,使更改生效。

测试

  1. 使用 ClickHouse 客户端登录,如下所示
  1. 创建表,并指定新的 S3 存储策略
  1. 验证该表是否已按正确的策略创建
  1. 向表中插入测试行
  1. 查看行
  1. 在 AWS 控制台中,进入存储桶列表,选择新建的存储桶和相应文件夹。 你应该会看到类似下面这样的内容:

使用 S3 对象存储在两个 AWS 区域之间复制单个分片

ClickHouse Cloud 默认使用对象存储,因此如果您使用的是 ClickHouse Cloud,则无需执行此过程。

规划部署

本教程以在 AWS EC2 上部署两个 ClickHouse Server 节点和三个 ClickHouse Keeper 节点为基础。ClickHouse Server 的数据存储使用 S3。为支持灾难恢复,使用了两个 AWS 区域,每个区域各包含一个 ClickHouse Server 和一个 S3 存储桶。 ClickHouse 表会在这两台服务器之间复制,因此也会跨这两个区域复制。

安装软件

ClickHouse 服务器 节点

在 ClickHouse 服务器 节点上执行部署步骤时,请参阅安装说明

部署 ClickHouse

在两台主机上部署 ClickHouse;在示例配置中,这两台主机分别命名为 chnode1chnode2 chnode1 部署在一个 AWS 区域中,将 chnode2 部署在另一个区域中。

部署 ClickHouse Keeper

在三台主机上部署 ClickHouse Keeper。在示例配置中,这些主机分别命名为 keepernode1keepernode2keepernode3keepernode1 可部署在与 chnode1 相同的区域,keepernode2 可部署在与 chnode2 相同的区域,而 keepernode3 可部署在任一区域,但需与该区域内的 ClickHouse 节点位于不同的可用区。 在 ClickHouse Keeper 节点上执行部署步骤时,请参阅安装说明

创建 S3 存储桶

创建两个 S3 存储桶,在放置 chnode1chnode2 的两个区域中各创建一个。 如果你需要有关创建存储桶和 IAM 角色 的分步说明,请展开 创建 S3 存储桶和 IAM 角色 并按步骤操作:
本文介绍配置 AWS IAM 用户、创建 S3 存储桶并将 ClickHouse 配置为使用该存储桶作为 S3 磁盘的基本步骤。 建议与您的安全团队共同确定所需权限,并将本文内容作为参考起点。

创建 AWS IAM 用户

在以下步骤中,您将创建一个服务账号用户 (而非登录用户) 。
  1. 登录 AWS IAM Management Console。
  2. Users 菜单中,选择 Create user
AWS IAM 管理控制台 - 添加新用户
  1. 输入用户名,将凭证类型设置为 Access key - Programmatic access,然后选择 Next: Permissions
为 IAM 用户设置用户名和访问类型
  1. 不要将用户添加到任何组;选择 Next: Tags
跳过为 IAM 用户分配组
  1. 如果无需添加任何标签,请选择 Next: Review
跳过为 IAM 用户分配标签
  1. 点击 Create User
提示用户无权限的警告信息可忽略;下一节将为该用户授予对此存储桶的权限
创建 IAM 用户时显示“无权限”警告
  1. 该用户现已创建;点击 show,然后复制访问密钥和机密密钥。
请将这些密钥另行保存;这是唯一一次可以查看该秘密访问密钥。
查看并复制 IAM 用户访问密钥
  1. 点击“关闭”,然后在“用户”页面中找到该用户。
在用户列表中找到新创建的 IAM 用户
  1. 复制 ARN (亚马逊资源名称) ,并保存下来,以便在配置存储桶的访问策略时使用。
复制 IAM 用户 ARN

创建 S3 存储桶

  1. 在 S3 存储桶部分,选择 Create bucket
开始创建 S3 存储桶
  1. 输入存储桶名称,其余选项保持默认即可
存储桶名称必须在整个 AWS 范围内唯一,而不只是组织内唯一,否则会报错。
  1. 保持 Block all Public Access 处于启用状态;无需公网访问。
配置已阻止公网访问的 S3 存储桶设置
  1. 在页面底部选择 Create Bucket
完成创建 S3 存储桶
  1. 点击该链接,复制 ARN,并将其保存起来,以便在为存储桶配置访问策略时使用。
  2. 创建存储桶后,在 S3 存储桶列表中找到新的 S3 存储桶并点击该链接
在存储桶列表中找到新创建的 S3 存储桶
  1. 选择 Create folder
在 S3 存储桶中新建文件夹
  1. 输入一个文件夹名称,作为 ClickHouse S3 磁盘的目标文件夹,然后选择 Create folder
为 ClickHouse 的 S3 磁盘设置文件夹名称
  1. 现在应可在存储桶列表中看到该文件夹
查看 S3 存储桶中新创建的文件夹
  1. 选中新建文件夹的复选框,然后点击 Copy URL。保存复制的 URL,以便在下一节的 ClickHouse 存储配置中使用。
复制用于配置 ClickHouse 的 S3 文件夹 URL
  1. 选择 Permissions 选项卡,然后在 Bucket Policy 部分点击 Edit 按钮
访问 S3 存储桶策略配置
  1. 添加存储桶策略,示例如下:
你应与安全团队协作,确定应使用哪些权限;这些内容可作为起点。 有关策略和设置的更多信息,请参阅 AWS 文档: https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-language-overview.html
  1. 保存策略配置。
随后,配置文件将放置到 /etc/clickhouse-server/config.d/ 中。以下是其中一个存储桶的配置文件样本;另一个与其类似,只有高亮的三行不同:
/etc/clickhouse-server/config.d/storage_config.xml
本指南中的许多步骤都会要求你将配置文件放到 /etc/clickhouse-server/config.d/ 中。这是 Linux 系统中用于存放配置覆盖文件的默认位置。将这些文件放入该目录后,ClickHouse 会使用其中的内容覆盖默认配置。把这些文件放在该覆盖目录中,可以避免在升级时丢失配置。

配置 ClickHouse Keeper

当 ClickHouse Keeper 以 standalone 模式运行 (与 ClickHouse 服务器 分离) 时,配置采用单个 XML 文件。在本教程中,该文件为 /etc/clickhouse-keeper/keeper_config.xml。3 个 Keeper server 使用相同的配置,只有一个设置项不同:<server_id> server_id 表示为使用该 configuration file 的主机分配的 ID。在下面的示例中,server_id3,如果继续查看文件下方的 <raft_configuration> 部分,你会看到 server 3 的 hostname 是 keepernode3。ClickHouse Keeper 进程正是通过这种方式,在选举 leader 以及执行其他各项操作时,知道需要连接哪些其他 server。
/etc/clickhouse-keeper/keeper_config.xml
将 ClickHouse Keeper 的配置文件复制到相应位置 (别忘了设置 <server_id>) :

配置 ClickHouse 服务器

定义集群

ClickHouse 集群是在配置的 <remote_servers> 部分中定义的。在此示例中,定义了一个集群 cluster_1S_2R,它由一个分片和两个副本组成。这两个副本分别位于主机 chnode1chnode2 上。
/etc/clickhouse-server/config.d/remote-servers.xml
在使用集群时,通常会定义宏,以便将 cluster、shard 和 replica 设置填入 DDL 查询。 此示例让你无需提供 shardreplica 详细信息,即可指定使用复制表引擎。 创建表后,你可以通过查询 system.tables 查看 shardreplica 宏是如何使用的。
/etc/clickhouse-server/config.d/macros.xml
上述宏用于 chnode1;在 chnode2 上,请将 replica 设置为 replica_2

禁用 zero-copy 复制

在 ClickHouse 22.7 及更低版本中,对于 S3 和 HDFS 磁盘,设置 allow_remote_fs_zero_copy_replication 默认值为 true。在此灾难恢复场景下,应将该设置设为 false;而在 22.8 及更高版本中,其默认值已为 false 该设置应设为 false,原因有二:1) 此功能尚未达到生产可用状态;2) 在灾难恢复场景中,数据和元数据都需要存储在多个区域。将 allow_remote_fs_zero_copy_replication 设为 false
/etc/clickhouse-server/config.d/remote-servers.xml
ClickHouse Keeper 负责协调 ClickHouse 节点之间的数据复制。要让 ClickHouse 了解 ClickHouse Keeper 节点信息,请在每个 ClickHouse 节点上添加一个配置文件。
/etc/clickhouse-server/config.d/use_keeper.xml

配置网络

在 AWS 中配置安全设置时,请参阅网络端口列表,以确保服务器之间能够互相通信,并且你也可以与它们通信。 这三台服务器都必须监听网络连接,以便服务器之间以及与 S3 之间能够通信。默认情况下,ClickHouse 仅监听回环地址,因此必须更改此设置。该配置位于 /etc/clickhouse-server/config.d/。下面是一个示例,用于将 ClickHouse 和 ClickHouse Keeper 配置为监听所有 IPv4 接口。有关更多信息,请参阅文档或默认配置文件 /etc/clickhouse/config.xml
/etc/clickhouse-server/config.d/networking.xml

启动各服务器

运行 ClickHouse Keeper

在每个 Keeper server 上,运行适用于你的操作系统的命令,例如:

检查 ClickHouse Keeper 状态

使用 netcat 向 ClickHouse Keeper 发送命令。例如,mntr 会返回 ClickHouse Keeper 集群的状态。如果你在每个 Keeper 节点上运行该命令,就会看到其中一个是 leader,另外两个是跟随者:

启动 ClickHouse 服务器

在每台 ClickHouse 服务器 上运行

验证 ClickHouse 服务器

添加集群配置时,系统定义了一个单分片集群,并在两个 ClickHouse 节点之间进行复制。在此验证步骤中,你将检查 ClickHouse 启动时是否已构建该集群,并使用该集群创建一个复制表。
  • 验证集群是否存在:
  • 使用 ReplicatedMergeTree 表引擎在集群中创建表:
  • 了解前面定义的宏的用途 shardreplica 已在前文中定义,在下面高亮显示的这一行中,你可以看到这些值在每个 ClickHouse 节点上是如何被替换的。此外,这里还使用了 uuiduuid 不在宏定义中,因为它是由系统生成的。
你可以通过设置 default_replica_pathdefault_replica_name,自定义上面显示的 ZooKeeper 路径 'clickhouse/tables/{uuid}/{shard}。相关文档见这里

测试

这些测试将验证数据是否已在两台服务器之间复制,以及数据是否存储在 S3 存储桶中而非本地磁盘。
  • 添加纽约市出租车数据集中的数据:
  • 验证数据已存储在 S3 中。 此查询会显示磁盘上数据的大小,以及用于确定使用哪个磁盘的存储策略。
    检查本地磁盘上的数据大小。根据上面的信息,存储的数百万行数据在磁盘上的大小为 36.42 MiB。这些数据应存储在 S3 上,而不是本地磁盘。上面的查询还会告诉我们数据和元数据在本地磁盘上的存储位置。检查本地数据:
    检查每个 S3 存储桶中的数据 (这里未显示总量,但插入后两个存储桶中都大约存储了 36 MiB):

S3Express

S3Express 是 Amazon S3 推出的一种新型高性能单可用区存储类别。 你可以参考这篇博客,了解我们在 ClickHouse 中测试 S3Express 的经验。
S3Express 将数据存储在单个可用区内。这意味着如果该可用区发生故障,数据将无法访问。

S3 磁盘

创建使用 S3Express 存储桶作为后端存储的表,需要执行以下步骤:
  1. 创建一个 Directory 类型的存储桶
  2. 配置合适的存储桶策略,为你的 S3 用户授予所有必需的权限 (例如,使用 "Action": "s3express:*" 可直接允许不受限制的访问)
  3. 配置存储策略时,请提供 region 参数
存储配置与普通 S3 相同,例如可以如下所示:
然后在新存储上创建一个表:

S3 存储

也支持 S3 存储,但仅支持 Object URL 路径。示例:
还需要在配置中指定存储桶所在区域:

备份

可以将备份存储到我们上面创建的磁盘中:
最后修改于 2026年7月23日