Настройка кластера ClickHouse Keeper в Debian 12 Bookworm

Содержание

Введение

Для координации работы узлов кластеров существует специальный сервис - ZooKeeper, первоначально разработанный в Yahoo. Его исходный код в дальнейшем был опубликован под лицензией Apache 2.0 и передан фонду Apache Software Foundation. ZooKeeper написан на языке программирования Java. Первоначально для координации работы узлов кластера ClickHouse использовался ZooKeeper. Сам сервер ClickHouse при этом написан на языке программирования C++. Видимо в первую очередь для того, чтообы не устраивать зверинец (получилась игра слов) из разных языков, разработчики сервера ClickHouse решили написать на C++ собственную реализацию сервиса координации, совместимую с ZooKeeper.

Для координации работы узлов кластера можно использовать и единственный узел ZooKeeper или ClickHouse Keeper. Но в таком случае надёжность кластера начинает зависеть от надёжности одного узла - координатора. Для того, чтобы в кластере не было единой точки отказа, обычно и сам координатор запускают в кластерной конфигурации из минимум трёх узлов.

Настройка самостоятельного узла

Настройка базовых репозиториев

Пропишем в файл /etc/apt/sources.list репозитории Debian 12 Bookworm, расположенные на зеркале mirror.ufanet.ru:

deb http://mirror.ufanet.ru/debian/ bookworm main contrib non-free-firmware
deb http://mirror.ufanet.ru/debian/ bookworm-updates main contrib non-free-firmware
deb http://mirror.ufanet.ru/debian/ bookworm-proposed-updates main contrib non-free-firmware
deb http://mirror.ufanet.ru/debian-security/ bookworm-security main contrib non-free-firmware

Отключим установку предлагаемых зависимостей, создав файл /etc/apt/apt.conf.d/suggests со следующим содержимым:

APT::Install-Suggests "false";

Отключим установку рекомендуемых зависимостей, создав файл /etc/apt/apt.conf.d/recommends со следующим содержимым:

APT::Install-Recommends "false";

Для ограничения объёма кэша пакетов 200 мегабайтами, хранящегося в каталоге /var/cache/apt/archives/, создадим файл /etc/apt/apt.conf.d/cache со следующим содержимым:

APT::Cache-Limit "209715200";

Чтобы уменьшить время ожидания при недоступности репозитория пятью секундами, создадим файл /etc/apt/apt.conf.d/timeouts со следующим содержимым:

Acquire::http::Timeout "5";
Acquire::https::Timeout "5";
Acquire::ftp::Timeout "5";

Обновим список пакетов, доступных через репозитории:

# apt-get update

Установка пакетов

Обновим уже установленные в системе пакеты:

# apt-get upgrade
# apt-get dist-upgrade

Установим дополнительные пакеты, которые могут пригодиться при работе с системой:

# apt-get install acpi-support-base vim less apt-file binutils sysstat tcpdump file dnsutils telnet psmisc traceroute net-tools man-db bzip2 ca-certificates apt-transport-https wget unzip sudo needrestart

Я привык использовать в качестве редактора по умолчанию vim, поэтому выберу его как системный редактор по умолчанию:

# update-alternatives --set editor /usr/bin/vim.basic

Настройка репозиториев ClickHouse

Устанавливаем утилиты, необходимые для установки GPG-ключа репозитория:

# apt-get install gpg dirmngr

Установим сам GPG-ключ репозитория:

# gpg --keyserver hkp://keyserver.ubuntu.com:80 --receive-key 3E4AD4719DDE9A38
# gpg --export --armor 3E4AD4719DDE9A38 > /etc/apt/trusted.gpg.d/clickhouse.asc

Пропишем в файл /etc/apt/sources.list репозиторий ClickHouse:

deb http://repo.yandex.ru/clickhouse/deb/ stable main

Обновим список пакетов, доступных через репозитории:

# apt-get update

Установка и настройка ClickHouse Keeper

Установим пакет:

# apt-get install clickhouse-keeper

В каталоге /etc/clickhouse-keeper находится файл keeper_config.xml. Файл хорошо прокомментирован, однако комментарии не мешают ориентироваться в файле, как это происходит в случае с файлами конфигурации сервера ClickHouse. Я лишь поменял уровень подробности сообщений, записываемых в журнал:

<clickhouse>
    <logger>
        <level>warning</level>

И удалил секцию, отвечающую за настройку сертификатов SSL/TLS:

<clickhouse>
    <openSSL>

Также нужно добавить в файл конфигурации следующую опцию:

<clickhouse>
    <path>/var/lib/clickhouse/coordination/keeper</path>

Без неё ClickHouse Keeper пытается обратиться к несуществующему каталогу /var/lib/clickhouse-keeper и завершает работу, сообщая об ошибке доступа в журнале /var/log/clickhouse-keeper/clickhouse-keeper.log:

2024.06.26 12:40:52.803791 [ 5144 ] {} <Error> Application: std::exception. Code: 1001, type: std::__1::__fs::filesystem::filesystem_error, e.what() = filesystem error: in create_directories: Permission denied ["/var/lib/clickhouse-keeper"], Stack trace (when copying this message, always include the lines below):

Теперь можно запустить ClickHouse Keeper в самостоятельном режиме:

# systemctl start clickhouse-keeper

После запуска ClickHouse Keeper ожидает подключений на локальном интерфейсе на TCP-порт 9181 и на TCP-порт 9234 со внешних адресов. Первый порт используется для обслуживания запросов от клиентов - узлов какго-либо кластерного приложения, а второй - для обмена информацией между узлами самого кластера ClickHouse Keeper. Для того, чтобы ClickHouse Keeper принимал подключения на TCP-порт 9181 извне, нужно прописать в файл конфигурации соответствующие настройки:

<clickhouse>
    <listen_host>0.0.0.0</listen_host>

По умолчанию в ClickHouse Keeper включена опция force_sync, которая предписывает после добавления в журнал новой записи координации делать системный вызов fsync и дожидаться окончания записи на диск. Применение этой опции даёт больше гарантий целостности данных, но приводит к высокой нагрузке на диски и к снижению отзывчивости ClickHouse Keeper. Каждые snapshot_distance новых записей (по умолчанию 100000) в журнал создаётся снимок состояния системы, который записывается на диск. Всего на диске хранится snapshots_to_keep (по умолчанию 3) таких мгновенных снимков, так что имеющихся гарантий надёжности должно быть достаточно и без включения опции force_sync. Отключим опцию force_sync в файле конфигурации:

<clickhouse>
    <force_sync>false</force_sync>

Для применеия новых настроек ClickHouse Keeper нужно перезапустить:

# systemctl restart clickhouse-keeper

Проверка режима работы

Для того, чтобы убедиться, что узел работает в самостоятельном режиме, установим утилиту nc:

# apt-get install netcat-openbsd

И узнаем состояние узла следующим образом:

$ echo mntr | nc localhost 9181 | awk '$1 == "zk_server_state" { print $2; }'

Если указанная выше команда вывела строку standalone, значит ClickHouse Keeper работает в самостотельном режиме.

Настройка кластера

Для настройки кластера из трёх узлов нужно повторить настройку самостоятельных узлов на ещё двух серверах или виртуальных машинах.

Настройка первого узла

Поменяем идентификатор узла и пропишем список узлов в файле конфигурации /etc/clickhouse-keeper/keeper_config.xml следующим образом:

<clickhouse>
    <keeper_server>
        <server_id>0</server_id>
        <raft_configuration>
            <server>
                <id>0</id>
                <hostname>ck0</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>1</id>
                <hostname>ck1</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>2</id>
                <hostname>ck2</hostname>
                <port>9234</port>
            </server>
        </raft_configuration>
    </keeper_server>
</clickhouse>

Если имена узлов не прописаны в DNS, для тестовых целей можно на каждом из узлов прописать имена в файл /etc/hosts, например, вот так:

192.168.122.15 ck0
192.168.122.16 ck1
192.168.122.17 ck2

Если ранее узел уже работал в самостоятельном режиме, а идентификатор узла в файле конфигурации при настройке поменялся, можно начать с чистого листа и удалить все имеющиеся файлы, в которых сохранено прежнее состояние узла:

# rm -R /var/lib/clickhouse/coordination/logs/* /var/lib/clickhouse/coordination/snapshots/* /var/lib/clickhouse/coordination/keeper/preprocessed_configs/*

Запустим первый узел с новыми настройками:

# systemctl restart clickhouse-keeper

Если сейчас заглянуть в журнал /var/log/clickhouse-keeper/clickhouse-keeper.log, то в нём будут повторяться сообщения, подобные приведённым ниже:

2024.06.26 15:26:43.899617 [ 504 ] {} <Error> RaftInstance: 1 nodes (out of 2, 2 including learners) are not responding longer than 10000 ms, at least 2 nodes (including leader) should be alive to proceed commit
2024.06.26 15:26:43.899672 [ 504 ] {} <Warning> RaftInstance: we cannot yield the leadership of this small cluster
2024.06.26 15:26:43.899983 [ 504 ] {} <Warning> RaftInstance: Receive AppendEntriesRequest from another leader (0) with same term, there must be a bug. Ignore it instead of exit.
2024.06.26 15:26:43.899999 [ 504 ] {} <Warning> RaftInstance: no response is returned from raft message handler

Запущен всего один узел, он не может образовать кворум и поэтому находится в режиме "только чтение".

Переведём первый узел в режим восстановления кластера, в котором один узел может продолжать работу без других узлов:

$ echo rcvr | nc localhost 9181

После подачи этой команды в журнале появится сообщение:

2024.06.26 15:42:31.771819 [ 493 ] {} <Warning> KeeperServer: This instance is in recovery mode. Until the quorum is restored, no requests should be sent to any of the cluster instances. This instance will start accepting requests only when the recovery is finished.

Настройка второго узла

Настроим второй узел точно так же, как был настроен первый узел, но поменяем в конфигурации /etc/clickhouse-keeper/keeper_config.xml его собстенный идентификатор следующим образом:

<clickhouse>
    <keeper_server>
        <server_id>1</server_id>
    </keeper_server>
</clickhouse>

Запустим ClickHouse Keeper:

# systemctl start clickhouse-keeper

И проверим его состояние:

$ echo mntr | nc localhost 9181 | awk '$1 == "zk_server_state" { print $2; }'

Если команда вывела значение follower, значит кластер из двух узлов уже запущен. Этот является ведомым, отвечает на операции чтения, а для выполнения операций записи обращается к ведущему узлу.

Поскольку в кластере пока всего два узла, первый узел сейчас должен выполнять роль ведущего. Такая же команда на первом узле должна вывести значение leader.

Настройка третьего узла

Настройка третьего узла полностью аналогична настройке второго, меняется только собственный идентификатор узла в конфигурации /etc/clickhouse-keeper/keeper_config.xml:

<clickhouse>
    <keeper_server>
        <server_id>2</server_id>
    </keeper_server>
</clickhouse>

Запустим ClickHouse Keeper:

# systemctl start clickhouse-keeper

И проверим его состояние:

$ echo mntr | nc localhost 9181 | awk '$1 == "zk_server_state" { print $2; }'

Если команда вывела значение follower, значит в кластер добавился ещё один ведомый узел.

Использованные материалы