ClickHouse учитывает, что GCS — привлекательное решение для хранения данных, если вам нужно разделить хранилище и вычислительные ресурсы. Для этого предусмотрена поддержка использования GCS в качестве хранилища для движка MergeTree. Это позволяет воспользоваться преимуществами GCS с точки зрения масштабируемости и стоимости, сохранив при этом производительность вставки и запросов движка MergeTree.
MergeTree на базе GCS
Создание диска
Чтобы использовать GCS-бакет в качестве диска, его сначала нужно объявить в конфигурации ClickHouse в файле из каталога conf.d. Ниже показан пример объявления GCS-диска. Эта конфигурация включает несколько секций для настройки GCS-«диска», кэша и политики, которая указывается в DDL-запросах при создании таблиц на GCS-диске. Каждая из них описана ниже.
Конфигурация хранилища > disks > gcs
Эта часть конфигурации показана в выделенном разделе и указывает следующее:
- Тип диска —
s3, поскольку используется API S3. - Конечная точка, предоставляемая GCS
- HMAC-ключ и secret service account
- Путь к metadata на локальном диске
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Конфигурация хранилища > disks > cache
В приведённом ниже примере конфигурации для диска gcs включён кэш в памяти объёмом 10 Gi.
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
<gcs_cache>
<type>cache</type>
<disk>gcs</disk>
<path>/var/lib/clickhouse/disks/gcs_cache/</path>
<max_size>10Gi</max_size>
</gcs_cache>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs_cache</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Конфигурация хранилища > policies > gcs_main
Политики конфигурации хранилища позволяют выбирать, где будут храниться данные. Показанная ниже политика позволяет хранить данные на диске gcs, указав политику gcs_main. Например, CREATE TABLE ... SETTINGS storage_policy='gcs_main'.
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Полный список настроек, относящихся к этому описанию диска, можно найти здесь.
Создание таблицы
Если ваш диск настроен на использование бакета с доступом на запись, вы сможете создать таблицу, как в примере ниже. Для краткости мы используем только часть столбцов из набора NYC taxi и передаём данные напрямую в таблицу на базе GCS:
CREATE TABLE trips_gcs
(
`trip_id` UInt32,
`pickup_date` Date,
`pickup_datetime` DateTime,
`dropoff_datetime` DateTime,
`pickup_longitude` Float64,
`pickup_latitude` Float64,
`dropoff_longitude` Float64,
`dropoff_latitude` Float64,
`passenger_count` UInt8,
`trip_distance` Float64,
`tip_amount` Float32,
`total_amount` Float32,
`payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4)
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'INSERT INTO trips_gcs SELECT trip_id, pickup_date, pickup_datetime, dropoff_datetime, pickup_longitude, pickup_latitude, dropoff_longitude, dropoff_latitude, passenger_count, trip_distance, tip_amount, total_amount, payment_type FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', NOSIGN, 'TabSeparatedWithNames') LIMIT 1000000;В зависимости от оборудования эта последняя вставка 1 млн строк может выполняться несколько минут. Ход выполнения можно проверить в таблице system.processes. При желании можно увеличить число строк до 10 млн и попробовать несколько примеров запросов.
SELECT passenger_count, avg(tip_amount) AS avg_tip, avg(total_amount) AS avg_amount FROM trips_gcs GROUP BY passenger_count;Настройка репликации
Репликацию с дисками GCS можно настроить с помощью движка таблицы ReplicatedMergeTree. Подробнее см. в руководстве по репликации одного сегмента между двумя регионами GCP с использованием GCS.
Подробнее
Cloud Storage XML API совместим с некоторыми инструментами и библиотеками, работающими с такими сервисами, как Amazon Simple Storage Service (Amazon S3).
Дополнительные сведения о настройке потоков см. в разделе Оптимизация производительности.
Использование Google Cloud Storage (GCS)
Спланируйте развертывание
Это руководство описывает развертывание ClickHouse с репликацией в Google Cloud, где Google Cloud Storage (GCS) используется в качестве типа диска хранения ClickHouse.
В этом руководстве вы развернете узлы сервера ClickHouse на виртуальных машинах Google Cloud Engine, при этом с каждым узлом будет связан отдельный GCS-бакет для хранения данных. Репликация координируется набором узлов ClickHouse Keeper, также развернутых на виртуальных машинах.
Примерные требования для высокой доступности:
- Два узла сервера ClickHouse в двух регионах GCP
- Два GCS-бакета, развернутые в тех же регионах, что и два узла сервера ClickHouse
- Три узла ClickHouse Keeper, два из которых развернуты в тех же регионах, что и узлы сервера ClickHouse. Третий может находиться в том же регионе, что и один из первых двух узлов Keeper, но в другой зоне доступности.
Для работы ClickHouse Keeper требуется два узла, поэтому для высокой доступности необходимы три узла.
Подготовьте виртуальные машины
Разверните пять виртуальных машин в трёх регионах:
| Регион | сервер ClickHouse | бакет | ClickHouse Keeper |
|---|---|---|---|
| 1 | chnode1 |
bucket_regionname |
keepernode1 |
| 2 | chnode2 |
bucket_regionname |
keepernode2 |
3 * |
keepernode3 |
* Это может быть другая зона доступности в том же регионе, что и 1 или 2.
Разверните ClickHouse
Разверните ClickHouse на двух хостах; в примерах конфигураций они обозначены как chnode1 и chnode2.
Разместите chnode1 в одном регионе GCP, а chnode2 — в другом. В этом руководстве для виртуальных машин Compute Engine, а также для бакетов GCS используются регионы us-east1 и us-east4.
При выполнении шагов развертывания на узлах сервера ClickHouse сверяйтесь с инструкциями по установке.
Развертывание ClickHouse Keeper
Разверните ClickHouse Keeper на трех хостах; в примерах конфигурации они называются keepernode1, keepernode2 и keepernode3. keepernode1 можно развернуть в том же регионе, что и chnode1, keepernode2 — вместе с chnode2, а keepernode3 — в любом из регионов, но в другой зоне доступности по сравнению с узлом ClickHouse в этом регионе.
При выполнении шагов развертывания на узлах ClickHouse Keeper обратитесь к инструкции по установке.
Создайте два бакета
Два сервера ClickHouse будут размещены в разных регионах для обеспечения высокой доступности. У каждого из них будет GCS-бакет в том же регионе.
В Cloud Storage > Buckets выберите CREATE BUCKET. В этом руководстве создаются два бакета: один в us-east1, другой — в us-east4. Бакеты создаются в одном регионе, со стандартным классом хранилища и без публичного доступа. При появлении соответствующего запроса включите запрет публичного доступа. Не создавайте папки — они будут созданы, когда ClickHouse начнет записывать данные в хранилище.
Если вам нужны пошаговые инструкции по созданию бакетов и HMAC-ключа, разверните Create GCS buckets and an HMAC key и следуйте инструкциям:
Создание бакетов GCS и ключа HMAC
ch_bucket_us_east1

ch_bucket_us_east4

Создание ключа доступа
Создание ключа и секрета HMAC для сервисного аккаунта
Откройте Cloud Storage > Settings > Interoperability и либо выберите существующий Access key, либо CREATE A KEY FOR A SERVICE ACCOUNT. В этом руководстве рассматривается создание нового ключа для нового сервисного аккаунта.

Добавление нового сервисного аккаунта
Если в этом проекте ещё нет сервисного аккаунта, выберите CREATE NEW ACCOUNT.

Создание сервисного аккаунта состоит из трёх шагов; на первом шаге задайте аккаунту понятные имя, идентификатор и описание.

В диалоговом окне настроек Interoperability рекомендуется роль IAM Storage Object Admin; выберите её на втором шаге.

Третий шаг необязателен и в этом руководстве не используется. Вы можете предоставить пользователям эти привилегии в соответствии с вашими политиками.

Будут показаны ключ HMAC и секрет сервисного аккаунта. Сохраните эти данные, так как они будут использоваться в конфигурации ClickHouse.

Настройка ClickHouse Keeper
У всех узлов ClickHouse Keeper один и тот же файл конфигурации, за исключением строки server_id (первая выделенная строка ниже). Измените файл, указав имена хостов для ваших серверов ClickHouse Keeper, и на каждом сервере задайте server_id так, чтобы он соответствовал нужной записи server в raft_configuration. Поскольку в этом примере для server_id задано значение 3, мы выделили соответствующие строки в raft_configuration.
- Измените файл, указав имена хостов, и убедитесь, что они разрешаются с узлов сервера ClickHouse и узлов Keeper
- Скопируйте файл в нужное место (
/etc/clickhouse-keeper/keeper_config.xmlна каждом из серверов Keeper - Измените
server_idна каждой машине в соответствии с номером её записи вraft_configuration
<clickhouse>
<logger>
<level>trace</level>
<log>/var/log/clickhouse-keeper/clickhouse-keeper.log</log>
<errorlog>/var/log/clickhouse-keeper/clickhouse-keeper.err.log</errorlog>
<size>1000M</size>
<count>3</count>
</logger>
<listen_host>0.0.0.0</listen_host>
<keeper_server>
<tcp_port>9181</tcp_port>
<server_id>3</server_id>
<log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
<coordination_settings>
<operation_timeout_ms>10000</operation_timeout_ms>
<session_timeout_ms>30000</session_timeout_ms>
<raft_logs_level>warning</raft_logs_level>
</coordination_settings>
<raft_configuration>
<server>
<id>1</id>
<hostname>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</hostname>
<port>9234</port>
</server>
</raft_configuration>
</keeper_server>
</clickhouse>Настройка сервера ClickHouse
Сетевые настройки
По умолчанию ClickHouse прослушивает только интерфейс loopback; в реплицированной конфигурации требуется сетевое взаимодействие между машинами. Включите прослушивание на всех интерфейсах:
<clickhouse>
<listen_host>0.0.0.0</listen_host>
</clickhouse>Удалённые серверы ClickHouse Keeper
Репликация координируется ClickHouse Keeper. В этом файле конфигурации узлы ClickHouse Keeper указываются по имени хоста и номеру порта.
- Измените имена хостов в соответствии с именами хостов ваших узлов Keeper
<clickhouse>
<zookeeper>
<node index="1">
<host>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</host>
<port>9181</port>
</node>
<node index="2">
<host>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</host>
<port>9181</port>
</node>
<node index="3">
<host>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</host>
<port>9181</port>
</node>
</zookeeper>
</clickhouse>Удалённые серверы ClickHouse
В этом файле задаются имя хоста и порт каждого сервера ClickHouse в кластере. В файле конфигурации по умолчанию содержатся примеры определений кластеров; чтобы отображались только полностью настроенные кластеры, в запись remote_servers добавлен тег replace="true". Благодаря этому при слиянии с конфигурацией по умолчанию секция remote_servers заменяется, а не дополняется.
- Измените файл, указав свои имена хостов, и убедитесь, что они разрешаются с узлов сервера ClickHouse
<clickhouse>
<remote_servers replace="true">
<cluster_1S_2R>
<shard>
<replica>
<host>chnode1.us-east1-b.c.clickhousegcs-374921.internal</host>
<port>9000</port>
</replica>
<replica>
<host>chnode2.us-east4-c.c.clickhousegcs-374921.internal</host>
<port>9000</port>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>
</clickhouse>Идентификация реплики
В этом файле настраиваются параметры, связанные с путём ClickHouse Keeper. В частности, здесь задаются макросы, используемые для определения того, к какой реплике относятся данные. На одном сервере реплика должна быть указана как replica_1, а на другом сервере — replica_2. Имена можно изменить: например, если одна реплика хранится в Южной Каролине, а другая — в Северной Виргинии, значениями могут быть carolina и virginia; просто убедитесь, что на каждой машине они различаются.
<clickhouse>
<distributed_ddl>
<path>/clickhouse/task_queue/ddl</path>
</distributed_ddl>
<macros>
<cluster>cluster_1S_2R</cluster>
<shard>1</shard>
<replica>replica_1</replica>
</macros>
</clickhouse>Хранилище в GCS
Конфигурация хранилища ClickHouse включает disks и policies. Настраиваемый ниже диск называется gcs и имеет type s3. Тип — s3, потому что ClickHouse обращается к GCS бакету как к AWS S3 бакету. Потребуются две копии этой конфигурации, по одной для каждого узла сервера ClickHouse.
В приведенной ниже конфигурации нужно выполнить следующие подстановки.
Эти подстановки различаются между двумя узлами сервера ClickHouse:
- Для
REPLICA 1 BUCKETдолжно быть указано имя бакета в том же регионе, что и сервер - Значение
REPLICA 1 FOLDERдолжно быть изменено наreplica_1на одном из серверов и наreplica_2на другом
Эти подстановки одинаковы для обоих узлов:
- В
access_key_idдолжен быть указан HMAC Key, сгенерированный ранее - В
secret_access_keyдолжен быть указан HMAC Secret, сгенерированный ранее
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/REPLICA 1 BUCKET/REPLICA 1 FOLDER/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
<cache>
<type>cache</type>
<disk>gcs</disk>
<path>/var/lib/clickhouse/disks/gcs_cache/</path>
<max_size>10Gi</max_size>
</cache>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Запустите ClickHouse Keeper
Используйте команды для вашей операционной системы, например:
sudo systemctl enable clickhouse-keeper
sudo systemctl start clickhouse-keeper
sudo systemctl status clickhouse-keeperПроверка состояния ClickHouse Keeper
Отправьте команды в ClickHouse Keeper с помощью netcat. Например, mntr возвращает состояние кластера ClickHouse Keeper. Если выполнить эту команду на каждом из узлов Keeper, вы увидите, что один из них — leader, а два других — followers:
echo mntr | nc localhost 9181zk_version v22.7.2.15-stable-f843089624e8dd3ff7927b8a125cf3a7a769c069
zk_avg_latency 0
zk_max_latency 11
zk_min_latency 0
zk_packets_received 1783
zk_packets_sent 1783
zk_num_alive_connections 2
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 135
zk_watch_count 8
zk_ephemerals_count 3
zk_approximate_data_size 42533
zk_key_arena_size 28672
zk_latest_snapshot_size 0
zk_open_file_descriptor_count 182
zk_max_file_descriptor_count 18446744073709551615
zk_followers 2
zk_synced_followers 2Запустите сервер ClickHouse
На chnode1 и chnode выполните:
sudo service clickhouse-server startsudo service clickhouse-server statusПроверка
Проверьте конфигурацию дисков
system.disks должен содержать записи для каждого диска:
- default
- gcs
- cache
SELECT *
FROM system.disks
FORMAT VerticalRow 1:
──────
name: cache
path: /var/lib/clickhouse/disks/gcs/
free_space: 18446744073709551615
total_space: 18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space: 0
type: s3
is_encrypted: 0
is_read_only: 0
is_write_once: 0
is_remote: 1
is_broken: 0
cache_path: /var/lib/clickhouse/disks/gcs_cache/
Row 2:
──────
name: default
path: /var/lib/clickhouse/
free_space: 6555529216
total_space: 10331889664
unreserved_space: 6555529216
keep_free_space: 0
type: local
is_encrypted: 0
is_read_only: 0
is_write_once: 0
is_remote: 0
is_broken: 0
cache_path:
Row 3:
──────
name: gcs
path: /var/lib/clickhouse/disks/gcs/
free_space: 18446744073709551615
total_space: 18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space: 0
type: s3
is_encrypted: 0
is_read_only: 0
is_write_once: 0
is_remote: 1
is_broken: 0
cache_path:
3 rows in set. Elapsed: 0.002 sec.Убедитесь, что таблицы в кластере созданы на обоих узлах
create table trips on cluster 'cluster_1S_2R' (
`trip_id` UInt32,
`pickup_date` Date,
`pickup_datetime` DateTime,
`dropoff_datetime` DateTime,
`pickup_longitude` Float64,
`pickup_latitude` Float64,
`dropoff_longitude` Float64,
`dropoff_latitude` Float64,
`passenger_count` UInt8,
`trip_distance` Float64,
`tip_amount` Float32,
`total_amount` Float32,
`payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4))
ENGINE = ReplicatedMergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.us-east4-c.c.gcsqa-375100.internal │ 9000 │ 0 │ │ 1 │ 1 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode1.us-east1-b.c.gcsqa-375100.internal │ 9000 │ 0 │ │ 0 │ 0 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
2 rows in set. Elapsed: 0.641 sec.Проверьте возможность вставки данных
INSERT INTO trips SELECT
trip_id,
pickup_date,
pickup_datetime,
dropoff_datetime,
pickup_longitude,
pickup_latitude,
dropoff_longitude,
dropoff_latitude,
passenger_count,
trip_distance,
tip_amount,
total_amount,
payment_type
FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', NOSIGN, 'TabSeparatedWithNames')
LIMIT 1000000Убедитесь, что для таблицы используется политика хранения gcs_main.
SELECT
engine,
data_paths,
metadata_path,
storage_policy,
formatReadableSize(total_bytes)
FROM system.tables
WHERE name = 'trips'
FORMAT VerticalRow 1:
──────
engine: ReplicatedMergeTree
data_paths: ['/var/lib/clickhouse/disks/gcs/store/631/6315b109-d639-4214-a1e7-afbd98f39727/']
metadata_path: /var/lib/clickhouse/store/e0f/e0f3e248-7996-44d4-853e-0384e153b740/trips.sql
storage_policy: gcs_main
formatReadableSize(total_bytes): 36.42 MiB
1 row in set. Elapsed: 0.002 sec.Проверьте в консоли Google Cloud
Просматривая бакеты, вы увидите, что в каждом из них была создана папка с именем, указанным в файле конфигурации storage.xml. Разверните папки, и вы увидите множество файлов, представляющих собой партиции данных.
Бакет для первой реплики

Бакет для второй реплики
