Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

SeaweedFS 目录

Experimental 功能

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。这种方式非常适合学习、原型开发和开发环境。

前置条件

  1. Docker 和 Docker Compose:确保已安装并运行 Docker
  2. 版本:SeaweedFS 4.42 或更高版本;ClickHouse 26.8 或更高版本 (25.8 及之后的版本可以读取和插入数据,但通过目录创建表需要 26.8)
  3. 安装了 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: bridge

mini 命令会在单个容器中启动完整的 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_credentialoauth_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`;
Navigation