Масштабирование кластера ClickHouse по горизонтали включает добавление дополнительных узлов для увеличения ёмкости хранилища, производительности запросов и отказоустойчивости. Это позволяет системе эффективно обрабатывать большие наборы данных и большее количество одновременных запросов.
1. Методы масштабирования ClickHouse по горизонтали
ClickHouse поддерживает две основные стратегии горизонтального масштабирования:
Стратегия масштабирования | Описание | Лучшее применение |
---|---|---|
Шардинг (Добавление новых шардов) | Разделяет данные по новым узлам | Большие наборы данных, высокая пропускная способность для записи |
Репликация (Добавление новых реплик) | Копирует данные на дополнительные узлы | Высокая доступность, отказоустойчивость, балансировка нагрузки |
2. Масштабирование ClickHouse по горизонтали с использованием шардинга
Шардинг распределяет данные по нескольким узлам, снижая нагрузку на каждый узел хранения данных.
Шаг 1: Добавление нового шарда в кластер
Обновите файл config.xml на всех узлах для добавления нового шарда.
<remote_servers>
<my_cluster>
<shard> <!-- Существующий Шард 1 -->
<replica>
<host>clickhouse1</host>
<port>9000</port>
</replica>
<replica>
<host>clickhouse2</host>
<port>9000</port>
</replica>
</shard>
<shard> <!-- Новый Шард 2 -->
<replica>
<host>clickhouse3</host>
<port>9000</port>
</replica>
<replica>
<host>clickhouse4</host>
<port>9000</port>
</replica>
</shard>
</my_cluster>
</remote_servers>
Перезапустите ClickHouse на каждом узле:
sudo systemctl restart clickhouse-server
Шаг 2: Создание локальных таблиц на новом шарде
На новых узлах (clickhouse3, clickhouse4) создайте ту же таблицу MergeTree:
CREATE TABLE events_local (
event_id UInt32,
event_time DateTime,
user_id UInt32
) ENGINE = MergeTree()
ORDER BY event_time;
Шаг 3: Обновление распределённой таблицы
На всех узлах обновите распределённую таблицу, чтобы она включала новый шард:
CREATE OR REPLACE TABLE events_distributed
ENGINE = Distributed(my_cluster, default, events_local, rand());
✅ Теперь новые запросы будут автоматически маршрутизироваться на новый шард!
Шаг 4: Перераспределение старых данных по шардом
🚨 Проблема: При добавлении нового шарда старые данные остаются неравномерно распределёнными.
✅ Решение: Перераспределите данные вручную.
✅ Шаг 1: Создание Временной Таблицы
Создайте временную таблицу для хранения данных, пока мы выполняем перераспределение.
CREATE TABLE events_temp AS events_local ENGINE = MergeTree() ORDER BY event_time;
✅ Эта таблица временно будет содержать все старые данные.
✅ Шаг 2: Копирование Данных из Распределённой Таблицы в Временную Таблицу
INSERT INTO events_temp SELECT * FROM events_distributed;
✅ Теперь в events_temp
содержатся все данные со всех старых шардов.
✅ Шаг 3: Удаление Старых Данных из Существующих Шардов
Удалите данные с существующих шардов, чтобы подготовить их к перераспределению.
ALTER TABLE events_local ON CLUSTER my_cluster DELETE WHERE 1;
✅ Теперь все шардовые таблицы пусты, но данные сохранены в events_temp
.
✅ Шаг 4: Повторное Вставление Данных через Распределённую Таблицу
Повторно вставьте данные из events_temp
в распределённую таблицу, что позволит перераспределить данные по всем шартам, включая новые.
INSERT INTO events_distributed SELECT * FROM events_temp;
🚀 Теперь ClickHouse перераспределит данные по ВСЕМ шартам, включая новые!
✅ Шаг 5: Удаление Временной Таблицы (Очистка)
Удалите временную таблицу после завершения процесса.
DROP TABLE events_temp;
3. Масштабирование ClickHouse по горизонтали с использованием репликации
Репликация добавляет больше копий существующих данных, улучшая производительность чтения, отказоустойчивость и доступность.
Шаг 1: Добавление реплики к существующему шарду
На новом узле создайте ту же таблицу ReplicatedMergeTree:
CREATE TABLE events_local (
event_id UInt32,
event_time DateTime,
user_id UInt32
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/shard1/events', '{replica}')
ORDER BY event_time;
✅ ClickHouse автоматически синхронизирует данные с новой репликой!
Шаг 2: Обновление распределённой таблицы
Обновите распределённую таблицу, чтобы запросы использовали новую реплику:
CREATE OR REPLACE TABLE events_distributed
ENGINE = Distributed(my_cluster, default, events_local, rand());
✅ Теперь ClickHouse будет распределять запросы по всем репликам!
4. Как ClickHouse обрабатывает балансировку нагрузки после масштабирования
- Для запросов: ClickHouse автоматически распределяет SELECT-запросы по репликам.
- Для вставок: Данные отправляются в один шард за раз (распределение через rand() или хэширование).
- Для отказоустойчивости: Если узел выходит из строя, запросы автоматически перенаправляются на доступные реплики.
✅ Включите prefer_localhost_replica
, чтобы оптимизировать маршрутизацию запросов:
SET prefer_localhost_replica = 1;
✅ Это обеспечит использование ближайшей доступной реплики, уменьшая сетевые задержки!
5. Резюме: Как масштабировать ClickHouse по горизонтали
Метод масштабирования | Шаги | Лучшее применение |
---|---|---|
Шардинг (Больше шардов) | Обновите config.xml → Создайте новые таблицы MergeTree → Обновите распределённую таблицу → Перераспределите данные | Большие наборы данных, высокая нагрузка на запись |
Репликация (Больше реплик) | Создайте таблицы ReplicatedMergeTree на новых узлах → Обновите распределённую таблицу → Запросы автоматически используют реплики | Высокая доступность, чтение с высокой нагрузкой |
🚀 Основной вывод:
- Шардинг улучшает производительность записи, распространяя данные по нескольким узлам.
- Репликация улучшает производительность чтения и защиту от сбоев.
- Перераспределение данных — это вручную выполняемый процесс при добавлении новых шардов.