Табличная функция s3 и тип диска S3 в ClickHouse совместимы с SeaweedFS — распределённым хранилищем объектов с открытым исходным кодом и S3-совместимым шлюзом. SeaweedFS нативно поддерживает запросы в стиле path-style, поэтому самоуправляемое хранилище работает без wildcard DNS. SeaweedFS также поддерживает таблицы Iceberg: в его бакетах таблиц данные хранятся в виде файлов Parquet, а встроенный REST-каталог Iceberg предоставляет метаданные таблиц. О выполнении запросов к ним через ту же конечную точку см. руководство по каталогу SeaweedFS.
Используйте SeaweedFS 4.42 или более новую версию. В более ранних версиях объект может быть удалён, если коммит его записи происходит одновременно с удалением родительской папки как пустой. Сразу после успешной записи это проявляется сообщением Object ... suddenly disappeared.
Запуск SeaweedFS на локальной машине
Для локального тестирования создайте файл s3config.json с учетными данными S3:
{
"identities": [
{
"name": "analyst",
"credentials": [
{
"accessKey": "your_access_key_id",
"secretKey": "your_secret_access_key"
}
],
"actions": ["Admin", "Read", "Write", "List", "Tagging"]
}
]
}Затем запустите весь стек SeaweedFS в одном контейнере — флаг -bucket создаст бакет при запуске:
docker run -d --name seaweedfs -p 8333:8333 \
-v "$(pwd)/s3config.json:/etc/seaweedfs/s3config.json" \
chrislusf/seaweedfs:latest \
mini -dir=/data -s3.config=/etc/seaweedfs/s3config.json -bucket=clickhouse -admin.port=12646-admin.port=12646 обеспечивает, чтобы административный порт gRPC, который SeaweedFS на его основе определяет, находился ниже диапазона эфемерных портов Linux, иначе при запуске его первым могло бы занять соединение.
Конечная точка S3 доступна на порту 8333; прежде чем продолжить, дождитесь ответа:
until curl -s -o /dev/null http://localhost:8333; do sleep 1; doneДополнительные бакеты можно создать в любое время с помощью команды echo "s3.bucket.create -name mybucket" | docker exec -i seaweedfs weed shell.
По умолчанию запись подтверждается после передачи операционной системе. Чтобы перед подтверждением выполнять fsync каждой записи на диск, включите fsync для бакета:
echo "fs.configure -locationPrefix=/buckets/clickhouse/ -fsync -apply" | \
docker exec -i seaweedfs weed shellMergeTree с бэкендом S3
Конфигурация MergeTree с бэкендом S3 совместима после внесения незначительных изменений:
<clickhouse>
<storage_configuration>
<disks>
<s3>
<type>s3</type>
<endpoint>http://seaweedfs:8333/clickhouse/tables/</endpoint>
<access_key_id>your_access_key_id</access_key_id>
<secret_access_key>your_secret_access_key</secret_access_key>
<region></region>
<metadata_path>/var/lib/clickhouse/disks/s3/</metadata_path>
</s3>
<s3_cache>
<type>cache</type>
<disk>s3</disk>
<path>/var/lib/clickhouse/disks/s3_cache/</path>
<max_size>10Gi</max_size>
</s3_cache>
</disks>
<policies>
<s3_main>
<volumes>
<main>
<disk>s3</disk>
</main>
</volumes>
</s3_main>
</policies>
</storage_configuration>
</clickhouse>Затем таблицы размещают данные в SeaweedFS с помощью политики хранения:
CREATE TABLE trips (id UInt64, rider String, fare Float64)
ENGINE = MergeTree
ORDER BY id
SETTINGS storage_policy = 's3_main';Чтобы локально кэшировать часто считываемые данные, создайте таблицу с SETTINGS disk = 's3_cache' — определённый выше кэш-диск является обёрткой для S3-диска.
Табличная функция s3
Табличная функция s3 читает и записывает объекты через одну и ту же конечную точку:
INSERT INTO FUNCTION s3(
'http://seaweedfs:8333/clickhouse/sample/trips.parquet',
'your_access_key_id',
'your_secret_access_key',
'Parquet'
)
SELECT number AS id, concat('rider_', toString(number % 10)) AS rider, number * 1.5 AS fare
FROM numbers(1000);
SELECT count()
FROM s3(
'http://seaweedfs:8333/clickhouse/sample/*.parquet',
'your_access_key_id',
'your_secret_access_key',
'Parquet'
);Глоб-шаблоны позволяют читать несколько объектов.
Резервное копирование и восстановление
BACKUP и RESTORE поддерживают конечную точку SeaweedFS в качестве пункта назначения S3:
BACKUP TABLE trips
TO S3('http://seaweedfs:8333/clickhouse/backups/trips1', 'your_access_key_id', 'your_secret_access_key');
--- DROP TABLE trips;
RESTORE TABLE trips
FROM S3('http://seaweedfs:8333/clickhouse/backups/trips1', 'your_access_key_id', 'your_secret_access_key');