Добавление и удаление реплик в кластер ClickHouse

Содержание

Добавление реплики в кластер

Предположим для простоты, что у нас имеется кластер, состоящий из одной реплики с именем ch0 и с макросом replica равным 0. Нужно добавить ещё одну реплику с именем ch0 и макросом replica равным 1.

Для начала на имеющейся рабочей реплике ch0 создадим скрипт под именем schema_for_replica.sh со следующим содержимым:

#!/bin/sh

clickhouse-client <<END
SELECT concat('CREATE DATABASE "', name, '" ENGINE = ', engine_full, ';')
FROM system.databases
WHERE name NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA')
FORMAT TSVRaw;
END

clickhouse-client <<END
SELECT
    replaceRegexpOne(concat(create_table_query, ';'), 'CREATE (TABLE|DICTIONARY|VIEW|LIVE VIEW|WINDOW VIEW)', 'CREATE \\1 IF NOT EXISTS')
FROM
    system.tables
WHERE
    database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA') AND
    create_table_query != '' AND
    name NOT LIKE '.inner.%%' AND
    name NOT LIKE '.inner_id.%%'
FORMAT TSVRaw
SETTINGS show_table_uuid_in_table_create_query_if_not_nil = 1;
END

clickhouse-client <<END
SELECT
    replaceRegexpOne(concat(create_table_query, ';'), '(CREATE MATERIALIZED VIEW)', '\\1 IF NOT EXISTS')
FROM
    system.tables
WHERE
    database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA') AND
    create_table_query != '' AND
    name NOT LIKE '.inner.%%' AND
    name NOT LIKE '.inner_id.%%' AND
                as_select != ''
FORMAT TSVRaw
SETTINGS show_table_uuid_in_table_create_query_if_not_nil = 1;
END

Дадим скрипту право на выполнение:

# chmod +x schema_for_replica.sh

Выполним скрипт с сохранением вывода в файл scheme.sql следующим образом:

# ./schema_for_replica.sh > schema.sql

Скопируем полученный файл на будущую реплику ch1, которую мы собираемся добавить в кластер.

Пропишем в конфигурации сервера ClickHouse в файле /etc/clickhouse-server/config.d/cluster_node.xml на настраиваемой реплике ch1 все имеющиеся в кластере реплики, включая настраиваемую. В нашем случае их будет только две - ch0 и ch1:

<clickhouse>
        <display_name>ch1</display_name>
        <macros>
                <shard>0</shard>
                <replica>1</replica>
                <cluster>имя_кластера</cluster>
        </macros>
        <remote_servers replace="1">
                <имя_кластера>
                        <secret>$3cr3tP4$$w0rd</secret>
                        <shard>
                                <internal_replication>true</internal_replication>
                                <replica>
                                        <host>ch0</host>
                                        <port>9000</port>
                                </replica>
                                <replica>
                                        <host>ch1</host>
                                        <port>9000</port>
                                </replica>
                        </shard>
                </имя_кластера>
        </remote_servers>
</clickhouse>

На уже работающей реплике конфигурацию пока что менять не нужно.

Теперь можно запустить сервер ClickHouse на настраиваемой реплике ch1 и выполнить на ней запросы из файла scheme.sql, например, с помощью такой команды:

# clickhouse-client < schema.sql

Сразу после создания таблицы сервер начнёт синхронизировать содержимое этой таблицы с другими репликами. Наблюдать за процессом репликации можно с помощью такой команды:

# watch "clickhouse-client -d system -q 'SELECT database, table, progress FROM replicated_fetches;'"

Вывод не очень информативный, поскольку не даёт представления о степени завершённости процесса, однако даёт возможность видеть, что синхронизация выполняется. По окончании синхронизации запрос будет возвращать пустой результат, а объём данных на диске должен сравняться с объёмом данных на диске другой реплики.

Осталось только создать необходимых пользователей и выдать им права доступа. Для этого можно воспользоваться скриптом, описанным в разделе по ссылке Настройка отображения хэшей паролей пользователей.

Теперь можно прописать новую реплику и в конфигурацию других уже имеющихся реплик. В нашем случае надо вписать новую реплику только в файл конфигурации реплики ch0.

Удаление реплики из кластера

Предположим, что кластер с репликацией данных состоит из двух узлов с именами ch0 и ch1, значения макросов replica для которых равны соответственно 0 и 1. И предположим, что мы хотим удалить из кластера узел ch0.

В таком случае первым делом нужно удалить из файлов конфигурации всех остальных узлов упоминание узла ch0. Соответствующие настройки должны находиться в одном из файлов каталога /etc/clickhouse-server/config.d/ в ветке, изображённой ниже:

<clickhouse>
        <remote_servers>
                <имя_кластера>
                        <shard>
                                <replica>

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

SELECT DISTINCT
    cluster,
    shard_num,
    replica_num,
    host_name,
    host_address,
    port,
    is_local,
    is_active
FROM system.clusters;

Теперь нужно удалить реплицируемые таблицы или базы данных на удаляемом узле ch0:

DROP TABLE db.table;

DROP DATABASE db;

Узел больше не участвует в репликации, но информация о нём всё ещё есть в координаторе ClickHouse Keeper. Удалить эту информацию об отсутствующем узле можно с помощью запроса, который нужно запустить на любом из актуальных узлов кластера. Запустим на узле ch1 команду для удаления реплики, соответствующей макросу 0:

SYSTEM DROP REPLICA '0';

На этом реплику можно считать удалённой. Для использования узла в самостотельном режиме не забудьте удалить из его конфигурации в одном из файлов из каталога /etc/clickhouse-server/config.d/ следующую ветку настроек:

<clickhouse>
        <remote_servers>

Перезапускать сервер не требуется - конфигурация будет применена автоматически.

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

Дополнительные материалы