返回

ClickHouse 接入 Amazon S3 Tables,实现湖仓就地分析与回写

RSS ClickHouse Blog AI 逐段翻译 发布 2026-11-11 08:00 收录于 11-12

有效阅读仅保存在当前浏览器,用于「为你」推荐;暂停或清除记录。

DataHot 速览

ClickHouse 通过 Iceberg REST 端点双向连接 Amazon S3 Tables,可直接就地查询 Iceberg 表、用 ClickHouse SQL 完成转换,并将结果回写供看板与 AI Agent 使用。文章以零售分析为例,说明该方案如何避免数据拷贝带来的成本、时效滞后、治理分散与厂商锁定问题,且适用于自管理版 ClickHouse。

为什么值得关注:展示湖仓开放格式与高性能查询引擎解耦的一种落地路径,对关注实时分析、数据集成与 Agent 数据供给的数据从业者有参考价值。

本文目录 15 节
  1. 为何要原地查询
  2. 解决方案概述
  3. 数据如何流动
  4. 先决条件
  5. 创建具有最小权限的 IAM 角色
  6. 演练:在 Amazon S3 Tables 上进行零售分析
  7. 场景
  8. 步骤 1:将 ClickHouse 连接到 S3 表存储桶
  9. 步骤 2:发现并查询表
  10. 步骤 3:转换以连接购买和退货
  11. 步骤 4:将结果写回 S3 Tables
  12. 代理驱动的分析
  13. 注意事项和限制
  14. 清理
  15. 结论

译文

AI 逐段翻译

本文最初由 AWS 发布。

越来越多的组织将事务性和运营性数据保存在 Apache Iceberg 等开放表格式中,以便不同的处理引擎能够处理这些数据。但高效地存储和组织数据只是工作的一半。当人类和智能体都需要快速、全面地访问数据时,数据往往需要被复制到具有不同处理引擎的独立系统中。这种复制构建成本高昂,一经创建就会过时,使治理碎片化,并将结果锁定在单一系统中。

Amazon S3 Tables 为 Apache Iceberg 提供完全托管、可扩展且经济高效的存储。它们以开放格式存储数据,供任何兼容 Iceberg 的引擎读取。ClickHouse 是一个高性能实时数据库,与 S3 Tables 结合使用时,无需迁移即可快速处理分析。

在本文中,我们展示如何利用两者之间的双向连接,将 ClickHouse 的高性能引擎直接用于 S3 Tables 中的数据。这种方法避免了将数据复制到独立系统中。你可以在原地查询 Iceberg 表,使用 ClickHouse SQL 运行转换,并将整理好的结果写回,同时 S3 Tables 仍然是唯一的开源事实来源。

我们通过一个零售分析用例带你走完连接工作流。然后我们展示同一模式如何扩展到需要对分析结果进行快速迭代访问的 AI 智能体工作负载。本演练适用于自管理的 ClickHouse 部署。

为何要原地查询

本演练中我们解决四个关键挑战:

  • 复制成本: 每条管道都消耗计算、存储和工程时间,用于复制你已经拥有的数据。
  • 数据过时: 副本的新鲜度仅取决于上次同步的时间,这常常导致分析师和智能体日常基于过时数据进行推理。
  • 治理蔓延: 每一份额外的副本都是另一个需要保护、审计和进行合规推理的地方。
  • 锁定: 如果结果只存在于某个引擎的专有格式中,其他工具若不再次导出就无法使用它们。

解决方案概述

图 1:解决方案概述

ClickHouse 使用 DataLakeCatalog 数据库引擎通过 Iceberg REST 端点连接到 Amazon S3 Tables。连接后,你的表桶会在 ClickHouse 中显示为一个数据库。你可以发现命名空间、查询现有 Iceberg 表、创建新表并写回结果,所有这些都使用标准 ClickHouse SQL。

两个系统承担不同的职责:

  • Amazon S3 Tables 管理存储、Iceberg 元数据以及自动表维护,包括压缩、快照过期和未引用文件清理。有关当前默认值,请参阅 S3 Tables 文档。
  • ClickHouse 提供分析引擎,包括列式处理、并行查询执行以及仅读取每个查询相关数据的能力。

数据如何流动

  • 源数据物理上位于 S3 Tables 中。除非你有意物化某个子集,否则 ClickHouse 不在本地存储任何数据。
  • 在读取时,ClickHouse 首先调用 Iceberg REST 目录以解析当前表元数据和快照,然后直接从 S3 仅读取相关的 Parquet 对象。
  • 在写入时,ClickHouse 将新的 Parquet 数据和 Iceberg 元数据对象写入 S3。然后它通过目录将表的根元数据指针更新为新快照来提交。这种原子指针交换意味着读者要么看到旧快照,要么看到新快照,绝不会看到部分写入。
  • 身份验证使用 AWS Signature Version 4。请求通过附加到 ClickHouse 所代入身份的 AWS Identity and Access Management(IAM)策略进行授权。
🔗 何时改用 AWS Glue Iceberg REST 端点: 本演练中我们使用直接的 S3 Tables 端点,因为它是将一个引擎连接到一个表桶的最直接路径。如果你的组织需要集中式目录治理、跨多个引擎的细粒度访问控制或跨账户访问,请改用 AWS Glue Iceberg REST 端点。

先决条件

开始前你需要以下条件:

  • ClickHouse 26.8 或更高版本(开源、自管理)。此处描述的 S3 Tables 读写路径尚未在 ClickHouse Cloud(托管选项)中普遍可用。
  • AWS 账户,具有创建 S3 Tables 桶和 IAM 角色的权限。
  • 一个至少包含一个命名空间的 Amazon S3 表桶。记下 AWS 区域和表桶 ARN(例如,arn:aws:s3tables:us-east-1:123456789012:bucket/retail-analytics)。
  • 从你的 ClickHouse 主机到区域 S3 Tables 端点(s3tables.<region>.amazonaws.com)的网络访问。
  • 一个具有 S3 Tables 最小权限的 IAM 角色。请参阅以下示例策略。

创建具有最小权限的 IAM 角色

ClickHouse 需要一个 AWS 身份来向 S3 Tables 目录进行身份验证,并代表你读写对象。与其授予广泛的账户访问权限,不如创建一个仅授予工作流所需 S3 Tables 操作的 IAM 角色。以下示例策略授予 ClickHouse 在单个表桶内列出、读取和写入表的权限。请将 AWS 区域、账户 ID 和桶名称替换为你自己的值。

1{2"Version":"2012-10-17",3"Statement":[4{5"Sid":"AllowS3TablesReadWrite",6"Effect":"Allow",7"Action":[8"s3tables:GetTableBucket",9"s3tables:ListTables",10"s3tables:ListNamespaces",11"s3tables:GetNamespace",12"s3tables:GetTable",13"s3tables:GetTableData",14"s3tables:GetTableMetadataLocation",15"s3tables:CreateTable",16"s3tables:PutTableData",17"s3tables:UpdateTableMetadataLocation"18],19"Resource":[20"arn:aws:s3tables:us-east-1:123456789012:bucket/retail-analytics",21"arn:aws:s3tables:us-east-1:123456789012:bucket/retail-analytics/*"22]23}24]25}

注意: 提交 Iceberg 写入的正确操作是 s3tables:UpdateTableMetadataLocation。当 ClickHouse 提交 INSERT INTO 写入时,该操作会更新表根元数据指针。请参阅支持的 Iceberg REST API 及其如何映射到 S3 Tables IAM 操作。作为安全最佳实践,请在 ClickHouse 配置文件或 SQL 语句中使用短期凭证。

ClickHouse 从标准 AWS 凭证链(环境变量、实例配置文件或配置文件)读取凭证,因此你的 SQL 语句中不会出现凭证。

演练:在 Amazon S3 Tables 上进行零售分析

本演练将 ClickHouse 连接到 S3 表存储桶,跨三个 Iceberg 表运行零售分析转换,并将整理后的结果写回 S3 Tables。

场景

一家零售商将三个 Iceberg 表存储在 S3 表存储桶的 retail 命名空间下。分析团队需要按产品、日期和区域细分,每日查看净销售额、售出件数、退货件数和退货率。

表描述关键列
retail.purchases每一笔已完成的购买order_id、product_id、region、purchased_at、sales_amount、units
retail.returns退回的商品order_id、product_id、returned_at、refund_amount、units_returned
retail.products产品目录product_id、product_name、category

目前,这需要执行多表连接,当分析师进行即席查询时运行缓慢。目标是在 ClickHouse 中运行一次连接,并将结果作为整理后的表 daily_product_performance 写回。之后,仪表板、报告和下游工具可以直接从 S3 Tables 以低延迟和高并发读取预聚合的结果。以下步骤演示如何将 ClickHouse 连接到 S3 Tables。

步骤 1:将 ClickHouse 连接到 S3 表存储桶

启用 Iceberg 目录集成和写入支持:

1-- Enable the DataLakeCatalog engine for Iceberg (required in ClickHouse 26.8)2SET allow_database_iceberg =1;34-- Enable writing back to Iceberg tables in S3 Tables5SET allow_insert_into_iceberg =1;

接下来,创建目录连接。替换为你自己的区域、账户 ID 和表存储桶名称:

1CREATE DATABASE retail_lakehouse2ENGINE = DataLakeCatalog(3'https://s3tables.us-east-1.amazonaws.com/iceberg'4)5SETTINGS6    catalog_type ='s3tables',7    region ='us-east-1',8    warehouse ='arn:aws:s3tables:us-east-1:123456789012:bucket/retail-analytics';

ClickHouse 使用主机上的 AWS 凭证链进行身份验证。SQL 语句中不嵌入任何凭证。warehouse 值是你的表存储桶的 ARN。你无需逐个注册每个表。

步骤 2:发现并查询表

列出通过该目录可见的所有表:

1SHOW TABLES FROM retail_lakehouse;

S3 Tables 使用单级命名空间。命名空间和表名作为单个标识符传递给 ClickHouse,因此必须使用反引号。注意:这适用于本演练中所有表引用。

1-- Query the first 10 rows from the purchases table2-- Backticks required: 'retail.purchases' is a single identifier3SELECT*4FROM retail_lakehouse.`retail.purchases`5LIMIT 10;

步骤 3:转换以连接购买和退货

运行分析查询。此查询将购买连接到退货,计算扣除退款后的净销售额,并按日期、产品和区域对结果分组:

1SELECT2    toDate(p.purchased_at) AS performance_date,   -- Truncate timestamp to date3    p.product_id,4    p.region,5-- Net sales = gross sales minus refunds (ifNull handles products with no returns)6sum(p.sales_amount) -sum(ifNull(r.refund_amount, 0)) AS net_sales,7sum(p.units) AS units_sold,8sum(ifNull(r.units_returned, 0)) AS units_returned,9-- Return rate as a ratio; nullIf prevents division by zero10sum(ifNull(r.units_returned, 0)) /nullIf(sum(p.units), 0) AS return_rate11FROM retail_lakehouse.`retail.purchases` AS p12LEFTJOIN13(14-- Pre-aggregate returns per order and product to avoid row multiplication15SELECT16        order_id,17        product_id,18sum(refund_amount) AS refund_amount,19sum(units_returned) AS units_returned20FROM retail_lakehouse.`retail.returns`21GROUPBY order_id, product_id22) AS r23ON p.order_id = r.order_id24AND p.product_id = r.product_id25GROUPBY26    performance_date,27    p.product_id,28    p.region;

ClickHouse 并行处理此查询,并且得益于 Iceberg 元数据和 Parquet 列裁剪,只从 S3 Tables 读取所需的列和行组。

步骤 4:将结果写回 S3 Tables

首先,通过同一目录连接在 retail 命名空间中创建目标表:

1CREATE TABLE retail_lakehouse.`retail.daily_product_performance`2(3    performance_date  Date,4    product_id        String,5    region            String,6    net_sales         Decimal(18, 2),7    units_sold        UInt64,8    units_returned    UInt64,9    return_rate       Float6410)11ENGINE = Iceberg;

然后使用 INSERT INTO ... SELECT 填充它。这会重新运行步骤 3 中的转换,并将输出直接写入 S3 Tables:

1INSERT INTO retail_lakehouse.`retail.daily_product_performance`2SELECT3    toDate(p.purchased_at) AS performance_date,4    p.product_id,5    p.region,6sum(p.sales_amount) -sum(ifNull(r.refund_amount, 0)) AS net_sales,7sum(p.units) AS units_sold,8sum(ifNull(r.units_returned, 0)) AS units_returned,9sum(ifNull(r.units_returned, 0)) /nullIf(sum(p.units), 0) AS return_rate10FROM retail_lakehouse.`retail.purchases` AS p11LEFTJOIN12(13SELECT14        order_id, product_id,15sum(refund_amount) AS refund_amount,16sum(units_returned) AS units_returned17FROM retail_lakehouse.`retail.returns`18GROUPBY order_id, product_id19) AS r20ON p.order_id = r.order_id21AND p.product_id = r.product_id22GROUPBY performance_date, p.product_id, p.region;

验证结果:

1SELECT*2FROM retail_lakehouse.`retail.daily_product_performance`3ORDERBY performance_date DESC, net_sales DESC4LIMIT 20;

The daily_product_performance 表现在作为标准 Iceberg 表存在于 S3 Tables 中。任何连接到同一表存储桶的 Iceberg 兼容引擎(Amazon Athena、Amazon Redshift、AWS Glue、Amazon EMR、DuckDB、Apache Spark、Trino 等)都可以发现并查询它,而无需重新运行连接。

代理驱动的分析

AI 代理可以在 AWS 服务(如 Amazon Bedrock)中运行,也可以在你自己的应用程序中运行。它们不在 ClickHouse 内部运行,也不直接访问 S3 Tables。相反,代理将 ClickHouse 作为工具或函数调用,ClickHouse 使用先前配置的 DataLakeCatalog 连接和 IAM 身份来查询 S3 Tables 并写回整理后的结果。

假设有一个代理负责调查特定区域产品退货激增的情况。代理工作流程如下:

  • 读取: 代理调用 ClickHouse(作为工具或函数)查询 S3 Tables 中的 retail.purchases 和 retail.returns,筛选出感兴趣的区域和时间窗口。
  • 分析: 基于第一个结果,代理运行后续查询:按产品类别的退货率、与上一时期的比较,或与近期促销的相关性。
  • 写入: 代理将其整理后的发现(例如一个 return_spike_investigation 表)通过 ClickHouse 写回 S3 Tables。
  • 共享: 其他代理、商业智能(BI)工具和分析师可以直接从 S3 Tables 读取调查结果,而无需重新运行分析。

图 2:使用 ClickHouse 和 Amazon S3 Tables 的 AI 代理工作流程

此架构有两个主要优势:

  • 速度: 代理通常执行一系列依赖查询,其中每个查询都依赖于前一个结果。ClickHouse 的并行、列式执行使每一步都保持快速,将代理总延迟从分钟级降低到秒级。
  • 可复用性: 将结果以开放的 Iceberg 格式写回 S3 Tables,可使工具、引擎和其他代理消费这些结果,而无需供应商锁定。

S3 Tables 仍然是源数据和派生结果的中央开放存储。ClickHouse 提供快速分析层,推动代理工作流程持续运行。

注意事项和限制

  • 单级命名空间: S3 Tables 通过其 Iceberg REST 端点支持单级命名空间。表以 namespace.table_name 形式寻址。
  • 区域可用性: S3 Tables 的可用性因 AWS 区域而异。部署前请查看 Amazon S3 Tables 文档 中的当前区域列表。
  • 删除表: S3 Tables Iceberg REST 端点仅支持带 DROP TABLE 的 purge=true。如果 ClickHouse 发出的删除操作未带该标志,你可能会收到 400 Bad Request。运行删除操作前请验证 ClickHouse 的默认行为。
  • 性能特征: 在对象存储上使用 ClickHouse 就地查询 Iceberg 表,与查询本地 MergeTree 表具有不同的延迟和吞吐量特征。对于探索、批量转换和低并发工作负载,请就地查询。对于需要在高并发下保持一致低延迟的仪表板和应用程序,ClickHouse 建议将数据物化到 MergeTree 中。
  • ClickHouse Cloud 支持: ClickHouse Cloud 对此工作流程的支持尚未正式可用。
  • 自动表维护: S3 Tables 会自动将较小的对象合并成较大的文件(默认目标:512 MB)、使旧快照过期并删除未引用的文件。你无需手动安排这些操作。

清理

如果你在跟随本文操作时创建了资源,请查看以下内容以避免产生持续费用:

  • S3 Tables: S3 Tables 有其自己的定价模型,基于存储、请求和压缩。删除你不再需要的任何测试表和命名空间。
  • ClickHouse: 如果你为 ClickHouse 启动了 Amazon Elastic Compute Cloud(Amazon EC2)实例,请在不使用时终止或停止它。
  • IAM 资源: 如果不再需要,请移除为本演练创建的 IAM 角色和策略。

结论

本文演示了一个使用 ClickHouse 分析 Amazon S3 Tables 中数据的实用工作流,且无需数据迁移。通过 Iceberg REST 端点将 ClickHouse 连接到 S3 Tables,你可以就地查询、转换和丰富你的 Iceberg 表。然后,你可以将整理后的结果写回,供任何兼容 Iceberg 的引擎使用。这解决了数据复制成本、数据陈旧、治理蔓延和供应商锁定等问题。

同样的读取-转换-写入模式可扩展到需要对分析数据进行快速、迭代访问的 AI 代理工作负载。在这两种情况下,S3 Tables 都作为共享的开源事实来源,而 ClickHouse 提供分析速度。

要开始使用,请创建一个 Amazon S3 表存储桶,使用本文中的步骤将其连接到 ClickHouse,然后开始就地查询你的 Iceberg 表。

这篇内容对你有用吗?

反馈只用于改善内容筛选,不等同于收藏

分享这条资讯
分享海报
保存图片
iOS 也可以长按图片保存