ClickHouse prend en charge l’intégration avec plusieurs catalogues (Unity, Glue, REST, Polaris, etc.). Ce guide vous explique les étapes à suivre pour interroger vos données à l’aide de ClickHouse et du catalogue Lakekeeper.
Lakekeeper est une implémentation open source de REST catalog pour Apache Iceberg qui fournit :
- une implémentation native en Rust offrant de hautes performances et une grande fiabilité
- la conformité de l’API REST avec la spécification REST catalog d’Iceberg
- l’intégration au stockage cloud avec un stockage compatible S3
Configuration de développement en local
Pour le développement et les tests en local, vous pouvez utiliser une configuration Lakekeeper conteneurisée. Cette approche est idéale pour l’apprentissage, le prototypage et les environnements de développement.
Prérequis
- Docker et Docker Compose : Assurez-vous que Docker est installé et en cours d’exécution
- Configuration d’exemple : Vous pouvez utiliser la configuration Docker Compose de Lakekeeper
Configuration d’un catalogue Lakekeeper local
Vous pouvez utiliser la configuration docker-compose officielle de Lakekeeper, qui fournit un environnement complet avec Lakekeeper, un backend PostgreSQL pour les métadonnées et MinIO pour le stockage objet.
Étape 1 : Créez un nouveau dossier dans lequel exécuter l’exemple, puis créez un fichier docker-compose.yml avec la configuration suivante :
version: '3.8'
services:
lakekeeper:
image: quay.io/lakekeeper/catalog:latest
environment:
- LAKEKEEPER__PG_ENCRYPTION_KEY=This-is-NOT-Secure!
- LAKEKEEPER__PG_DATABASE_URL_READ=postgresql://postgres:postgres@db:5432/postgres
- LAKEKEEPER__PG_DATABASE_URL_WRITE=postgresql://postgres:postgres@db:5432/postgres
- RUST_LOG=info
command: ["serve"]
healthcheck:
test: ["CMD", "/home/nonroot/lakekeeper", "healthcheck"]
interval: 1s
timeout: 10s
retries: 10
start_period: 30s
depends_on:
migrate:
condition: service_completed_successfully
db:
condition: service_healthy
minio:
condition: service_healthy
ports:
- 8181:8181
networks:
- iceberg_net
migrate:
image: quay.io/lakekeeper/catalog:latest-main
environment:
- LAKEKEEPER__PG_ENCRYPTION_KEY=This-is-NOT-Secure!
- LAKEKEEPER__PG_DATABASE_URL_READ=postgresql://postgres:postgres@db:5432/postgres
- LAKEKEEPER__PG_DATABASE_URL_WRITE=postgresql://postgres:postgres@db:5432/postgres
- RUST_LOG=info
restart: "no"
command: ["migrate"]
depends_on:
db:
condition: service_healthy
networks:
- iceberg_net
bootstrap:
image: curlimages/curl
depends_on:
lakekeeper:
condition: service_healthy
restart: "no"
command:
- -w
- "%{http_code}"
- "-X"
- "POST"
- "-v"
- "http://lakekeeper:8181/management/v1/bootstrap"
- "-H"
- "Content-Type: application/json"
- "--data"
- '{"accept-terms-of-use": true}'
- "-o"
- "/dev/null"
networks:
- iceberg_net
initialwarehouse:
image: curlimages/curl
depends_on:
lakekeeper:
condition: service_healthy
bootstrap:
condition: service_completed_successfully
restart: "no"
command:
- -w
- "%{http_code}"
- "-X"
- "POST"
- "-v"
- "http://lakekeeper:8181/management/v1/warehouse"
- "-H"
- "Content-Type: application/json"
- "--data"
- '{"warehouse-name": "demo", "project-id": "00000000-0000-0000-0000-000000000000", "storage-profile": {"type": "s3", "bucket": "warehouse-rest", "key-prefix": "", "assume-role-arn": null, "endpoint": "http://minio:9000", "region": "local-01", "path-style-access": true, "flavor": "minio", "sts-enabled": true}, "storage-credential": {"type": "s3", "credential-type": "access-key", "aws-access-key-id": "minio", "aws-secret-access-key": "ClickHouse_Minio_P@ssw0rd"}}'
- "-o"
- "/dev/null"
networks:
- iceberg_net
db:
image: bitnami/postgresql:16.3.0
environment:
- POSTGRESQL_USERNAME=postgres
- POSTGRESQL_PASSWORD=postgres
- POSTGRESQL_DATABASE=postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -p 5432 -d postgres"]
interval: 2s
timeout: 10s
retries: 5
start_period: 10s
volumes:
- postgres_data:/bitnami/postgresql
networks:
- iceberg_net
minio:
image: bitnami/minio:2025.4.22
environment:
- MINIO_ROOT_USER=minio
- MINIO_ROOT_PASSWORD=ClickHouse_Minio_P@ssw0rd
- MINIO_API_PORT_NUMBER=9000
- MINIO_CONSOLE_PORT_NUMBER=9001
- MINIO_SCHEME=http
- MINIO_DEFAULT_BUCKETS=warehouse-rest
networks:
iceberg_net:
aliases:
- warehouse-rest.minio
ports:
- "9002:9000"
- "9003:9001"
healthcheck:
test: ["CMD", "mc", "ls", "local", "|", "grep", "warehouse-rest"]
interval: 2s
timeout: 10s
retries: 3
start_period: 15s
volumes:
- minio_data:/bitnami/minio/data
clickhouse:
image: clickhouse/clickhouse-server:head
container_name: lakekeeper-clickhouse
user: '0:0' # Ensures root permissions
ports:
- "8123:8123"
- "9000:9000"
volumes:
- clickhouse_data:/var/lib/clickhouse
- ./clickhouse/data_import:/var/lib/clickhouse/data_import # Mount dataset folder
networks:
- iceberg_net
environment:
- CLICKHOUSE_DB=default
- CLICKHOUSE_USER=default
- CLICKHOUSE_DO_NOT_CHOWN=1
- CLICKHOUSE_PASSWORD=
depends_on:
lakekeeper:
condition: service_healthy
minio:
condition: service_healthy
volumes:
postgres_data:
minio_data:
clickhouse_data:
networks:
iceberg_net:
driver: bridgeÉtape 2 : Exécutez la commande suivante pour démarrer les services :
docker compose up -dÉtape 3 : Attendez que tous les services soient prêts. Vous pouvez consulter les logs :
docker-compose logs -fSe connecter au catalogue Lakekeeper local
Connectez-vous à votre conteneur ClickHouse :
docker exec -it lakekeeper-clickhouse clickhouse-clientCréez ensuite la connexion de base de données au catalogue Lakekeeper :
SET allow_experimental_database_iceberg = 1;
CREATE DATABASE demo
ENGINE = DataLakeCatalog('http://lakekeeper:8181/catalog', 'minio', 'ClickHouse_Minio_P@ssw0rd')
SETTINGS catalog_type = 'rest', storage_endpoint = 'http://minio:9002/warehouse-rest', warehouse = 'demo'Interroger les tables du catalogue Lakekeeper avec ClickHouse
Maintenant que la connexion est établie, vous pouvez commencer à interroger le catalogue Lakekeeper. Par exemple :
USE demo;
SHOW TABLES;Si votre installation inclut des données d’exemple (comme le jeu de données des taxis), vous devriez voir des tables comme :
┌─name──────────┐
│ default.taxis │
└───────────────┘Pour interroger une table (si elle est disponible) :
SELECT count(*) FROM `default.taxis`;┌─count()─┐
│ 2171187 │
└─────────┘Pour afficher le DDL de la table :
SHOW CREATE TABLE `default.taxis`;┌─statement─────────────────────────────────────────────────────────────────────────────────────┐
│ CREATE TABLE demo.`default.taxis` │
│ ( │
│ `VendorID` Nullable(Int64), │
│ `tpep_pickup_datetime` Nullable(DateTime64(6)), │
│ `tpep_dropoff_datetime` Nullable(DateTime64(6)), │
│ `passenger_count` Nullable(Float64), │
│ `trip_distance` Nullable(Float64), │
│ `RatecodeID` Nullable(Float64), │
│ `store_and_fwd_flag` Nullable(String), │
│ `PULocationID` Nullable(Int64), │
│ `DOLocationID` Nullable(Int64), │
│ `payment_type` Nullable(Int64), │
│ `fare_amount` Nullable(Float64), │
│ `extra` Nullable(Float64), │
│ `mta_tax` Nullable(Float64), │
│ `tip_amount` Nullable(Float64), │
│ `tolls_amount` Nullable(Float64), │
│ `improvement_surcharge` Nullable(Float64), │
│ `total_amount` Nullable(Float64), │
│ `congestion_surcharge` Nullable(Float64), │
│ `airport_fee` Nullable(Float64) │
│ ) │
│ ENGINE = Iceberg('http://minio:9002/warehouse-rest/warehouse/default/taxis/', 'minio', '[HIDDEN]') │
└───────────────────────────────────────────────────────────────────────────────────────────────┘Chargement des données de votre lac de données vers ClickHouse
Si vous devez charger des données depuis le catalogue Lakekeeper dans ClickHouse, commencez par créer une table ClickHouse locale :
CREATE TABLE taxis
(
`VendorID` Int64,
`tpep_pickup_datetime` DateTime64(6),
`tpep_dropoff_datetime` DateTime64(6),
`passenger_count` Float64,
`trip_distance` Float64,
`RatecodeID` Float64,
`store_and_fwd_flag` String,
`PULocationID` Int64,
`DOLocationID` Int64,
`payment_type` Int64,
`fare_amount` Float64,
`extra` Float64,
`mta_tax` Float64,
`tip_amount` Float64,
`tolls_amount` Float64,
`improvement_surcharge` Float64,
`total_amount` Float64,
`congestion_surcharge` Float64,
`airport_fee` Float64
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(tpep_pickup_datetime)
ORDER BY (VendorID, tpep_pickup_datetime, PULocationID, DOLocationID);Chargez ensuite les données de la table de votre catalogue Lakekeeper via un INSERT INTO SELECT :
INSERT INTO taxis
SELECT * FROM demo.`default.taxis`;