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
- Docker e Docker Compose: verifique se o Docker está instalado e em execução
- 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)
- 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: bridgeO 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 -dInserindo 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-clientEm 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`;