Чтобы масштабировать кластер, измените количество реплик и сегментов в пользовательском ресурсе. Оператор приводит работающий кластер к новой топологии: создает или удаляет StatefulSet для каждой реплики, синхронизирует схему и отражает ход выполнения в состояниях статуса.
В этом руководстве описано, как масштабировать реплики и сегменты ClickHouseCluster, как безопасно масштабировать кворум KeeperCluster и за какими состояниями нужно следить во время операции масштабирования.
Масштабирование реплик
spec.replicas задаёт количество реплик в каждом сегменте. Каждая реплика запускается в собственном StatefulSet с именем <cluster>-clickhouse-<shard>-<replica>, поэтому в кластере с shards: 2 и replicas: 3 будет запущено шесть StatefulSets.
Увеличьте или уменьшите это количество прямо в существующей конфигурации:
spec:
replicas: 3 # was 1
keeperClusterRef:
name: my-keeperПри масштабировании вверх оператор создает новые StatefulSets для каждой реплики, ждет, пока каждый под перейдет в состояние Ready, а затем синхронизирует схему с новыми репликами (см. Автоматическая синхронизация схемы). При масштабировании вниз он удаляет лишние StatefulSets и очищает устаревшие записи о репликах реплицируемой базы данных, оставшиеся после удаления реплик.
Масштабирование сегментов
spec.shards задаёт количество сегментов. Каждый новый сегмент добавляет полный набор StatefulSet для каждой реплики, а оператор создаёт один PodDisruptionBudget на сегмент, чтобы сбой в одном сегменте не учитывался при расчёте для другого.
spec:
shards: 3 # was 1
replicas: 2Каждый сегмент хранит отдельную часть данных, и оператор не копирует и не перемещает строки между сегментами. Таблица Distributed или явная схема маршрутизации определяет, в какой сегмент попадёт строка, поэтому добавление сегмента просто даёт новым записям новое место для записи, не затрагивая строки, уже хранящиеся в существующих сегментах.
Автоматическая синхронизация схемы
Когда spec.settings.enableDatabaseSync имеет значение true (по умолчанию), оператор поддерживает согласованность схемы при изменении топологии:
- При масштабировании вверх — как только готовы как минимум две реплики, оператор реплицирует определения баз данных на вновь созданные реплики, чтобы новая реплика присоединилась с теми же базами данных
Replicatedи базами данных интеграций, что и остальные узлы кластера. - При масштабировании вниз — прежде чем реплика исчезнет, оператор удаляет регистрацию этой реплики из каждой базы данных
Replicatedс помощьюSYSTEM DROP DATABASE REPLICA, чтобы уменьшенный кластер не ожидал реплику базы данныхReplicated, которой больше не существует.
Это относится к базам данных Replicated и движкам баз данных интеграций. Табличные данные при этом не перемещаются — данные строк хранятся в таблицах ReplicatedMergeTree и реплицируются через Keeper независимо от этой синхронизации схемы. Если готова только одна реплика, реплицировать некуда, поэтому оператор пропускает этот шаг и записывает в журнал, что целевой реплики нет.
Установите enableDatabaseSync: false, чтобы отключить это поведение, например если за распространение схемы отвечает внешний инструмент. В этом случае оператор указывает причину SchemaSyncDisabled в условии SchemaInSync.
Состояния, за которыми стоит следить
Проверяйте состояние пользовательского ресурса во время операции масштабирования:
kubectl get clickhousecluster sample -o yaml | sed -n '/conditions:/,/^[^ ]/p'| Условие | Причина | Значение |
|---|---|---|
ClusterSizeAligned |
UpToDate |
Число запущенных реплик соответствует запрошенной топологии |
ClusterSizeAligned |
ScalingUp |
Оператор добавляет реплики |
ClusterSizeAligned |
ScalingDown |
Оператор удаляет реплики |
SchemaInSync |
ReplicasInSync |
Базы данных есть на всех репликах, а устаревшие метаданные удалены |
SchemaInSync |
DatabasesNotCreated |
Оператор еще не завершил создание баз данных на новых репликах |
SchemaInSync |
ReplicasNotCleanedUp |
Устаревшие метаданные реплик после уменьшения числа реплик еще не удалены |
SchemaInSync |
SchemaSyncDisabled |
enableDatabaseSync имеет значение false |
Ready |
AllShardsReady |
В каждом сегменте есть готовая реплика |
Ready |
SomeShardsNotReady |
Как минимум в одном сегменте нет готовой реплики |
Операция масштабирования считается завершенной, когда ClusterSizeAligned имеет значение UpToDate, SchemaInSync — ReplicasInSync, а Ready — AllShardsReady.
Масштабирование Keeper
KeeperCluster работает с RAFT-кворумом, поэтому оператор изменяет его состав по одной реплике за раз и только когда кластер находится в стабильном состоянии. Это защищает кворум: кластер 2F+1 допускает отказ F участников, поэтому кластер из 3 узлов продолжает работать при отсутствии одного участника, а кластер из 5 узлов — двух.
spec:
replicas: 5 # was 3При масштабировании вверх оператор добавляет в кворум реплику с наименьшим свободным ID; при масштабировании вниз — удаляет реплику с наибольшим ID. На каждом шаге оператор ждёт, пока кворум стабилизируется, прежде чем начинать следующий. Для Keeper PodDisruptionBudget по умолчанию задано maxUnavailable: replicas/2, чтобы сохранять кворум во время плановых прерываний.
Условие ScaleAllowed показывает, может ли кворум изменить состав прямо сейчас:
| Причина | Значение |
|---|---|
ReadyToScale |
Кворум стабилен, и оператор может добавить или удалить участника |
ReplicaHasPendingChanges |
У реплики всё ещё есть ожидающее применения изменение конфигурации |
ReplicaNotReady |
Реплика не готова, поэтому изменение состава откладывается |
NoQuorum |
В кластере нет кворума, и безопасно изменить состав нельзя |
WaitingFollowers |
Оператор ждёт, пока followers догонят лидера |
Масштабируйте Keeper по одному шагу и давайте ScaleAllowed вернуться к ReadyToScale между изменениями. Переход сразу на несколько участников не отменяет пошаговое согласование — оператор всё равно изменяет кворум по одному участнику за шаг.