ClickHouse 支持集成多个目录 (Unity、Glue、REST、Polaris 等) 。本指南将介绍如何使用 ClickHouse 和 SeaweedFS 目录查询数据。
SeaweedFS 是开源的分布式文件和对象存储,提供兼容 S3 的网关。其 S3 Table Buckets 同时提供 Iceberg 部署所需的两个组件:内嵌的 Iceberg REST 目录提供表元数据,存储桶则通过同一 S3 端点以 Parquet 文件形式存储表数据:
- 单一服务 - 目录元数据和 Parquet 数据均由同一进程提供,无需单独的元数据数据库
- REST API - 符合 Iceberg REST 目录规范
- 服务端维护 - 自动执行 Parquet 合并整理和快照过期处理,无需外部维护服务
本地开发环境搭建
对于本地开发和测试,您可以使用 Docker Compose 运行 SeaweedFS 和 ClickHouse。这种方式非常适合学习、原型开发和开发环境。
前置条件
- Docker 和 Docker Compose:确保已安装并运行 Docker
- 版本:SeaweedFS 4.42 或更高版本;ClickHouse 26.8 或更高版本 (25.8 及之后的版本可以读取和插入数据,但通过目录创建表需要 26.8)
- 安装了 PyIceberg 的 Python (可选) :用于在下文中填充样本数据
设置本地 SeaweedFS 目录
**第 1 步:**创建一个新文件夹以运行示例,然后创建包含 S3 网关和目录凭据的 s3config.json 文件:
{
"identities": [
{
"name": "analyst",
"credentials": [
{
"accessKey": "tutorialkey",
"secretKey": "tutorialsecret"
}
],
"actions": ["Admin", "Read", "Write", "List", "Tagging"]
}
]
}**第 2 步:**创建 docker-compose.yml 文件,并添加以下配置:
services:
seaweedfs:
image: chrislusf/seaweedfs:latest
command: mini -dir=/data -s3.config=/etc/seaweedfs/s3config.json -tableBucket=analytics -admin.port=12646
ports:
- "8333:8333" # S3 endpoint
- "8181:8181" # Iceberg REST catalog
volumes:
- ./s3config.json:/etc/seaweedfs/s3config.json
- seaweedfs_data:/data
networks:
- iceberg_net
clickhouse:
image: clickhouse/clickhouse-server:latest
container_name: seaweedfs-clickhouse
ports:
- "8123:8123"
- "9000:9000"
depends_on:
- seaweedfs
networks:
- iceberg_net
volumes:
seaweedfs_data:
networks:
iceberg_net:
driver: bridgemini 命令会在单个容器中启动完整的 SeaweedFS 技术栈。-tableBucket=analytics 标志会预先创建一个名为 analytics 的 S3 Tables 存储桶,作为 Iceberg 仓库。-admin.port=12646 可确保 SeaweedFS 据此派生的管理 gRPC 端口低于 Linux 临时端口范围,否则启动时建立的连接可能会抢先占用该端口。
**第 3 步:**运行以下命令启动服务:
docker compose up -d写入样本数据
目录初始为空。使用 PyIceberg (pip install pyiceberg pyarrow) 创建一个表,并追加几行数据:
import pyarrow as pa
from pyiceberg.catalog.rest import RestCatalog
catalog = RestCatalog(
"seaweedfs",
uri="http://localhost:8181",
warehouse="s3://analytics",
credential="tutorialkey:tutorialsecret",
**{
"s3.endpoint": "http://localhost:8333",
"s3.access-key-id": "tutorialkey",
"s3.secret-access-key": "tutorialsecret",
"s3.region": "us-east-1",
"s3.path-style-access": "true",
},
)
rows = pa.table({
"id": pa.array([1, 2, 3, 4, 5, 6], pa.int64()),
"region": ["NA", "EU", "EU", "APAC", "NA", "EU"],
"amount": pa.array([12.5, 40.0, 7.25, 99.9, 3.5, 61.0], pa.float64()),
})
catalog.create_namespace("sales")
table = catalog.create_table("sales.orders", schema=rows.schema)
table.append(rows)连接到本地 SeaweedFS 目录
连接到您的 ClickHouse 容器:
docker exec -it seaweedfs-clickhouse clickhouse-client然后创建与 SeaweedFS 目录的数据库连接:
SET allow_experimental_database_iceberg = 1;
CREATE DATABASE lake
ENGINE = DataLakeCatalog('http://seaweedfs:8181/v1', 'tutorialkey', 'tutorialsecret')
SETTINGS catalog_type = 'rest',
warehouse = 's3://analytics',
storage_endpoint = 'http://seaweedfs:8333/analytics',
catalog_credential = 'tutorialkey:tutorialsecret',
oauth_server_uri = 'http://seaweedfs:8181/v1/oauth/tokens'引擎 参数包含 ClickHouse 读取表数据所需的 S3 凭据;catalog_credential 和 oauth_server_uri 则通过 OAuth2 客户端凭据流程对目录本身进行身份验证。SeaweedFS 对两者均可使用相同的访问密钥和密钥。
使用 ClickHouse 查询 SeaweedFS 目录中的表
连接建立后,您可以开始通过 SeaweedFS 目录查询数据。例如:
USE lake;
SHOW TABLES;┌─name─────────┐
│ sales.orders │
└──────────────┘查询表:
SELECT region, sum(amount) AS total
FROM `sales.orders`
GROUP BY region
ORDER BY total DESC;┌─region─┬──total─┐
│ EU │ 108.25 │
│ APAC │ 99.9 │
│ NA │ 16 │
└────────┴────────┘从 ClickHouse 创建表并写入数据
您还可以在 SeaweedFS 目录中创建表,并直接通过 ClickHouse 向其中写入数据:
SET allow_experimental_database_iceberg = 1;
SET allow_experimental_insert_into_iceberg = 1;
SET write_full_path_in_iceberg_metadata = 1;
CREATE TABLE lake.`sales.returns` (id Int64, reason String)
ENGINE = IcebergS3('http://seaweedfs:8333/analytics/sales/returns/', 'tutorialkey', 'tutorialsecret');
INSERT INTO lake.`sales.returns` VALUES (1, 'damaged'), (2, 'wrong size');
SELECT * FROM lake.`sales.returns` ORDER BY id;┌─id─┬─reason─────┐
│ 1 │ damaged │
│ 2 │ wrong size │
└────┴────────────┘IcebergS3 引擎子句指定新表的存储路径,write_full_path_in_iceberg_metadata 使 ClickHouse 将完整的表位置注册到目录中。
当 ClickHouse 提交插入操作时,SeaweedFS 目录会修复实验性 writer 尚未生成的元数据:补全清单中缺失的字段 ID,将相对于存储桶的文件路径重写为绝对位置,并为表设置默认的名称映射。随后,PyIceberg 和 Spark 等严格 reader 即可读取 ClickHouse 写入的行。这需要 SeaweedFS 4.42 或更高版本。
将数据从数据湖加载到 ClickHouse
如需将 SeaweedFS 目录中的数据加载到 ClickHouse,请先创建一个本地 ClickHouse 表:
CREATE TABLE default.orders
(
`id` Int64,
`region` String,
`amount` Float64
)
ENGINE = MergeTree()
ORDER BY (region, id);然后使用 INSERT INTO SELECT 将 SeaweedFS 目录表中的数据加载到 ClickHouse:
INSERT INTO default.orders
SELECT * FROM lake.`sales.orders`;