Настройка ClickHouse Keeper
ClickHouse Keeper — это встроенная распределенная координационная служба ClickHouse, отвечающая за работу репликации и выполнение распределенных DDL-запросов. Keeper полностью совместим по протоколу с ZooKeeper, но реализован на C++ и использует алгоритм консенсуса RAFT, что обеспечивает линейризуемые записи и более предсказуемое поведение при отказах.
Отдельная настройка ClickHouse Keeper требуется только в кластерных сценариях: когда у вас есть несколько узлов ClickHouse и используются реплицируемые таблицы (ReplicatedMergeTree) или распределенные запросы ON CLUSTER. В односерверной установке Keeper не обязателен и может быть не развернут.
Варианты развертывания Keeper
ClickHouse Keeper может работать в двух режимах:
-
Как отдельный сервис. Устанавливается пакетом
clickhouse-keeperи запускается как отдельный процесс со своим конфигурационным файлом:- основной файл конфигурации:
/etc/clickhouse-keeper/keeper_config.xml - дополнительные файлы:
/etc/clickhouse-keeper/keeper_config.d/*.xmlили*.yaml
- основной файл конфигурации:
-
Как часть процесса
clickhouse-server. В этом случае конфигурационный блок<keeper_server>добавляется в основную конфигурацию сервера:- основной файл:
/etc/clickhouse-server/config.xml - либо отдельный файл в
/etc/clickhouse-server/config.d/keeper.xml
- основной файл:
Рекомендуемый подход для production — отдельные узлы ClickHouse Keeper и отдельные конфигурационные файлы в /etc/clickhouse-keeper/, чтобы независимым образом масштабировать и обслуживать координационный кластер.
Базовая структура конфигурации ClickHouse Keeper
Основной блок конфигурации Keeper — это элемент <keeper_server>. В типичном виде он включает:
Блок конфигурации Keeper
<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>10</count>
</logger>
<max_connections>4096</max_connections>
<listen_host>0.0.0.0</listen_host>
<keeper_server>
<!-- Порт, на котором клиенты (ClickHouse-серверы или приложения) подключаются к Keeper -->
<tcp_port>9181</tcp_port>
<!-- Уникальный идентификатор узла Keeper в кластере -->
<server_id>1</server_id>
<log_storage_path>/var/lib/clickhouse/coordination/logs</log_storage_path>
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
<!-- Внутренние настройки координации -->
<coordination_settings>
<operation_timeout_ms>10000</operation_timeout_ms>
<min_session_timeout_ms>10000</min_session_timeout_ms>
<session_timeout_ms>100000</session_timeout_ms>
<raft_logs_level>information</raft_logs_level>
<compress_logs>false</compress_logs>
</coordination_settings>
<!-- enable sanity hostname checks for cluster configuration (e.g. if localhost is used with remote endpoints) -->
<hostname_checks_enabled>true</hostname_checks_enabled>
<!-- Описание всех узлов Keeper, участвующих в кворуме -->
<raft_configuration>
<server>
<id>1</id>
<!-- Internal port and hostname -->
<hostname>ch-keeper-01</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<!-- Internal port and hostname -->
<hostname>ch-keeper-02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<!-- Internal port and hostname -->
<hostname>ch-keeper-03</hostname>
<port>9234</port>
</server>
<!-- Add more servers here -->
</raft_configuration>
</keeper_server>
<openSSL>
<server>
<!-- Used for secure tcp port -->
<!-- openssl req -subj "/CN=localhost" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt -->
<!-- <certificateFile>/etc/clickhouse-keeper/server.crt</certificateFile> -->
<!-- <privateKeyFile>/etc/clickhouse-keeper/server.key</privateKeyFile> -->
<!-- dhparams are optional. You can delete the <dhParamsFile> element.
To generate dhparams, use the following command:
openssl dhparam -out /etc/clickhouse-keeper/dhparam.pem 4096
Only file format with BEGIN DH PARAMETERS is supported.
-->
<!-- <dhParamsFile>/etc/clickhouse-keeper/dhparam.pem</dhParamsFile> -->
<verificationMode>none</verificationMode>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
</openSSL>
</clickhouse>
Ключевые параметры:
tcp_port— порт для клиентских подключений (ClickHouse-серверы,clickhouse-keeper-client, утилиты). Рекомендуемое значение —9181(во избежание конфликта со стандартным портом ZooKeeper2181)server_id— уникальный числовой идентификатор узла Keeper. Значения должны быть уникальными. Рекомендуется простая последовательность1, 2, 3, ...log_storage_path— путь к журналам RAFT-координацииsnapshot_storage_path— каталог для снапшотов состояния (сжатое состояние дерева znode)coordination_settings— детальная настройка таймаутов, частоты heartbeat-сообщений, параметров снапшотов и логов. В большинстве случаев достаточно базовых значений из примераraft_configuration— описание всех участников RAFT-кворума
Кластер Keeper должен состоять из нечетного числа узлов (обычно 3 или 5). Это необходимо для достижения кворума и повышения отказоустойчивости.
Настройка RAFT-кворума (<raft_configuration>)
Блок <raft_configuration> описывает все узлы Keeper, которые участвуют в кворуме RAFT:
<raft_configuration>
<secure>false</secure>
<server>
<id>1</id>
<hostname>ch-keeper-01</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>ch-keeper-02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>ch-keeper-03</hostname>
<port>9234</port>
</server>
</raft_configuration>
Для каждого <server> задаются:
id— идентификатор сервера в кворуме RAFT. Он должен совпадать сserver_idв<keeper_server>на соответствующем узлеhostname— имя хоста, по которому другие узлы могут связаться с этим Keeper. Рекомендуется использовать DNS-имена, а не IP-адреса, чтобы сохранять стабильное соответствиеserver_id↔hostnameport— порт внутреннего взаимодействия между узлами Keeper (межсерверный RAFT-порт). Он отличается отtcp_port, который используется клиентами
При замене или переносе Keeper-узла важно не переиспользовать старый server_id для другого физического сервера и не "перемешивать" соответствия server_id ↔ hostname. Это критично для корректности RAFT-кворума.
Внутренние настройки координации
Блок <coordination_settings> отвечает за таймауты и параметры работы RAFT:
<coordination_settings>
<operation_timeout_ms>10000</operation_timeout_ms>
<min_session_timeout_ms>10000</min_session_timeout_ms>
<session_timeout_ms>100000</session_timeout_ms>
<raft_logs_level>information</raft_logs_level>
<compress_logs>false</compress_logs>
</coordination_settings>
В большинстве случаев достаточно использовать рекомендуемые значения. Их изменение имеет смысл только при явных проблемах (частые пере-выборы лидера, нестабильная сеть, очень большой объем метаданных).
Размещение конфигурации и запуск Keeper
Отдельный сервис clickhouse-keeper
В этом варианте:
- основной файл конфигурации:
/etc/clickhouse-keeper/keeper_config.xml - дополнительные файлы:
/etc/clickhouse-keeper/keeper_config.d/*.xmlили*.yaml
После настройки конфигурации выполните следующие команды:
sudo systemctl enable clickhouse-keeper
sudo systemctl start clickhouse-keeper
sudo systemctl status clickhouse-keeper
Альтернативно, можно запустить Keeper напрямую:
clickhouse-keeper --config /etc/clickhouse-keeper/keeper_config.xml
# или
clickhouse keeper --config /etc/clickhouse-keeper/keeper_config.xml
Встроенный Keeper в процессе clickhouse-server
Если Keeper запускается как часть clickhouse-server, блок <keeper_server> добавляется в конфигурацию сервера:
<clickhouse>
<!-- ... прочие настройки ClickHouse ... -->
<keeper_server> ... </keeper_server>
</clickhouse>
После изменения конфигурации достаточно перезапустить сервер:
sudo systemctl restart clickhouse-server
В этом случае процесс ClickHouse и Keeper общий. В production-окружениях такой вариант обычно используют только для небольших тестовых стендов.
Интеграция ClickHouse Keeper с ClickHouse Server
Со стороны ClickHouse-серверов ClickHouse Keeper выглядит как ZooKeeper-совместимый сервис. На каждом узле ClickHouse необходимо указать координаторов в раззделе <zookeeper>:
<clickhouse>
<!-- ... -->
<zookeeper>
<node>
<host>ch-keeper-01</host>
<port>9181</port>
</node>
<node>
<host>ch-keeper-02</host>
<port>9181</port>
</node>
<node>
<host>ch-keeper-03</host>
<port>9181</port>
</node>
</zookeeper>
<!-- Макросы для настройки реплицируемых таблиц -->
<macros>
<cluster>cluster_name</cluster>
<shard>01</shard>
<replica>01</replica>
</macros>
</clickhouse>
Важно, чтобы список узлов в <zookeeper> соответствовал фактической конфигурации Keeper-кластера (тем же hostname и tcp_port, которые заданы в <keeper_server>).
Параметр <listen_host> и особенности IPv6
По умолчанию ClickHouse создает несколько записей listen_host, чтобы слушать локальный интерфейс по IPv4 и IPv6 (127.0.0.1 и ::1). Если требуется принимать подключения с других хостов, обычно добавляют строку:
<listen_host>0.0.0.0</listen_host>
Это wildcard-адрес только для IPv4: сервер будет слушать все IPv4-интерфейсы узла, но не будет открывать порты на IPv6. Для систем, где используется только IPv4, такой вариант предпочтителен и дополнительно снимает ряд проблем с IPv6.
На некоторых дистрибутивах IPv6 в ядре отключен или не настроен. В этом случае попытка слушать wildcard-адрес IPv6 может приводить к ошибкам.
<listen_host>::</listen_host>
Если на сервере фактически нет IPv6-поддержки, рекомендуется:
-
не использовать
<listen_host>::</listen_host> -
явно указать IPv4-вариант:
<listen_host>0.0.0.0</listen_host> -
при необходимости дополнительно отключить IPv6 в конфигурации ClickHouse/Keeper:
<enable_ipv6>false</enable_ipv6>
Это заставит ClickHouse слушать только IPv4-интерфейсы и избавит от ошибок, связанных с отсутствием IPv6.
Если в инфраструктуре используется IPv6 и сервер должен принимать подключения по обоим протоколам, вместо 0.0.0.0 можно использовать wildcard-адрес IPv6:
<listen_host>::</listen_host>
В этом случае ClickHouse откроет порты сразу на всех IPv6- и IPv4-интерфейсах (при условии, что IPv6 включен в системе). Такой режим стоит включать только в сочетании с корректной настройкой фаервола, сетевых ACL и политик доступа пользователей.
Проверка работоспособности ClickHouse Keeper
Через ClickHouse
С точки зрения ClickHouse-серверов состояние Keeper можно проверить запросом к системной таблице system.zookeeper:
SELECT *
FROM system.zookeeper
WHERE path IN ('/', '/clickhouse');
Наличие узлов /clickhouse и служебных веток (например, /clickhouse/task_queue/ddl) говорит о том, что Keeper доступен и используется для координации.
Через утилиту clickhouse-keeper-client
ClickHouse содержит консольную утилиту clickhouse-keeper-client, которая умеет работать с Keeper по его нативному протоколу:
clickhouse-keeper-client -h ch-keeper-01 -p 9181
В интерактивном режиме доступны команды, похожие на ZooKeeper-клиент:
ls /— просмотр дочерних znodeget '/clickhouse'— чтение значения узлаset '/clickhouse/test' 'value'— запись значенияexists '/clickhouse'— проверка существования узла
Это удобный способ проверки доступности Keeper и диагностики содержимого дерева znode.
Four-letter команды
Как и ZooKeeper, ClickHouse Keeper поддерживает набор «четырехбуквенных» команд, которые отправляются на клиентский порт по TCP, например через nc:
echo mntr | nc ch-keeper-01 9181
- команда
mntrвыводит значения метрик: состояние узла (лидер/фолловер), количество подключений, задержки и т.д. - команда
statпоказывает краткую сводку о состоянии сервера и клиентов, аruokпроверяет доступность службы (возвращаетimokпри работоспособности)
Рекомендации по эксплуатации
- для production-кластеров рекомендуется минимум 3 узла ClickHouse Keeper на отдельных хостах или контейнерах
- при изменении топологии кластера (добавление/удаление Keeper-узлов) внимательно следите за тем, чтобы не нарушить уникальность
server_idи соответствиеserver_id ↔ hostnameво всех конфигурациях