Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Catálogo do SeaweedFS

Recurso experimental

O ClickHouse oferece integração com vários catálogos (Unity, Glue, REST, Polaris etc.). Este guia apresenta as etapas para consultar seus dados usando o ClickHouse e o catálogo SeaweedFS.

O SeaweedFS é um armazenamento distribuído de arquivos e objetos de código aberto com um gateway compatível com S3. Seus S3 Table Buckets fornecem os dois componentes de uma implantação do Iceberg: o catálogo REST do Iceberg embutido fornece os metadados das tabelas, e o bucket de tabelas armazena os dados das tabelas como arquivos Parquet no mesmo endpoint S3:

  • Serviço único - os metadados do catálogo e os dados Parquet são fornecidos por um único processo, sem um banco de dados de metadados separado
  • Conformidade da API REST com a especificação do catálogo REST do Iceberg
  • Manutenção no servidor - compactação automática de arquivos Parquet e expiração de snapshots, sem serviço de manutenção externo

Configuração para desenvolvimento local

Para desenvolvimento e testes locais, você pode executar o SeaweedFS e o ClickHouse com o Docker Compose. Essa abordagem é ideal para aprendizado, prototipagem e ambientes de desenvolvimento.

Pré-requisitos

  1. Docker e Docker Compose: verifique se o Docker está instalado e em execução
  2. Versões: SeaweedFS 4.42 ou posterior; ClickHouse 26.8 ou posterior (as versões desde a 25.8 podem ler e inserir, mas a criação de tabelas pelo catálogo requer a versão 26.8)
  3. Python com PyIceberg (opcional): usado abaixo para inserir dados de exemplo

Configurar o catálogo local do SeaweedFS

Etapa 1: Crie uma nova pasta para executar o exemplo e, em seguida, crie um arquivo s3config.json com as credenciais do gateway S3 e do catálogo:

{
  "identities": [
    {
      "name": "analyst",
      "credentials": [
        {
          "accessKey": "tutorialkey",
          "secretKey": "tutorialsecret"
        }
      ],
      "actions": ["Admin", "Read", "Write", "List", "Tagging"]
    }
  ]
}

Etapa 2: Crie um arquivo docker-compose.yml com a seguinte configuração:

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

O comando mini inicia toda a stack do SeaweedFS em um único contêiner. A flag -tableBucket=analytics cria antecipadamente um bucket do S3 Tables chamado analytics, que funciona como warehouse do Iceberg. -admin.port=12646 mantém a porta gRPC de administração derivada pelo SeaweedFS abaixo da faixa de portas efêmeras do Linux, evitando que uma conexão de inicialização a reserve primeiro.

Passo 3: Execute o seguinte comando para iniciar os serviços:

docker compose up -d

Inserindo dados de exemplo

O catálogo está inicialmente vazio. Crie uma tabela e acrescente algumas linhas usando o 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)

Como se conectar ao catálogo local do SeaweedFS

Conecte-se ao contêiner do ClickHouse:

docker exec -it seaweedfs-clickhouse clickhouse-client

Em seguida, crie a conexão com o banco de dados no catálogo do 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'

Os argumentos do engine contêm as credenciais do S3 usadas pelo ClickHouse para ler os dados da tabela, enquanto catalog_credential e oauth_server_uri autenticam no próprio catálogo por meio do fluxo OAuth2 de credenciais de cliente. O SeaweedFS aceita a mesma chave de acesso e chave secreta para ambos.

Consultando tabelas do catálogo do SeaweedFS com o ClickHouse

Agora que a conexão foi estabelecida, você pode começar a fazer consultas por meio do catálogo do SeaweedFS. Por exemplo:

USE lake;

SHOW TABLES;
┌─name─────────┐
│ sales.orders │
└──────────────┘

Para consultar uma tabela:

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 │
└────────┴────────┘

Criar tabelas e gravar dados do ClickHouse

Você também pode criar tabelas no catálogo do SeaweedFS e gravar dados nelas diretamente do 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 │
└────┴────────────┘

A cláusula do engine IcebergS3 especifica o caminho de armazenamento da nova tabela, e write_full_path_in_iceberg_metadata faz com que o ClickHouse registre a localização completa da tabela no catálogo.

Quando o ClickHouse confirma um insert, o catálogo do SeaweedFS corrige metadados que o writer experimental ainda não produz: preenche IDs de campo ausentes nos manifests, reescreve caminhos de arquivos relativos ao bucket como localizações absolutas e atribui um mapeamento de nomes padrão à tabela. Leitores rigorosos, como PyIceberg e Spark, podem então ler as linhas gravadas pelo ClickHouse. Isso requer o SeaweedFS 4.42 ou posterior.

Carregando dados do seu lago de dados para o ClickHouse

Se precisar carregar dados do catálogo do SeaweedFS no ClickHouse, comece criando uma tabela local no ClickHouse:

CREATE TABLE default.orders
(
    `id` Int64,
    `region` String,
    `amount` Float64
)
ENGINE = MergeTree()
ORDER BY (region, id);

Em seguida, carregue os dados da tabela do catálogo do SeaweedFS usando um INSERT INTO SELECT:

INSERT INTO default.orders
SELECT * FROM lake.`sales.orders`;
Navigation