Распределённые таблицы в ClickHouse направляют запросы через несколько шардов и реплик, что позволяет обеспечивать горизонтальное масштабирование, балансировку нагрузки и отказоустойчивость в кластере.
1. Что такое распределённая таблица?
Распределённая таблица:
- Не хранит данные непосредственно (служит маршрутизатором запросов).
- Направляет чтение и запись в локальные таблицы на разных шардах.
- Позволяет выполнять запросы параллельно на нескольких узлах.
- Улучшает отказоустойчивость, перенаправляя запросы к доступным репликам.
Процесс работы распределённой таблицы
+-------------------------------+
| Запрос клиента (SELECT, INSERT) |
+-------------------------------+
|
v
+--------------------------------+
| Распределённая таблица (Маршрутизатор запросов) |
+--------------------------------+
|
+-------------------+-------------------+
| | |
v v v
+-------------+ +-------------+ +-------------+
| Шард 1 | | Шард 2 | | Шард 3 | (Данные)
| Реплика A | | Реплика A | | Реплика A |
| Реплика B | | Реплика B | | Реплика B |
+-------------+ +-------------+ +-------------+
✅ Запросы автоматически распределяются между узлами.
✅ Отказоустойчивость — если одна реплика выходит из строя, запросы перенаправляются на другую.
2. Как создать распределённую таблицу
Для использования распределённой таблицы необходимо:
- Локальная таблица (MergeTree) на каждом шарде.
- Распределённая таблица, которая маршрутизирует запросы.
Шаг 1: Создание локальной таблицы на каждом узле Создайте эту таблицу на каждом шарде:
CREATE TABLE events_local (
event_id UInt32,
event_time DateTime,
user_id UInt32
) ENGINE = MergeTree()
ORDER BY event_time;
✅ Каждый узел хранит часть данных.
Шаг 2: Создание распределённой таблицы Создайте распределённую таблицу на всех узлах для маршрутизации запросов.
CREATE TABLE events_distributed
ENGINE = Distributed(my_cluster, default, events_local, rand());
Разбор параметров:
my_cluster
→ Определён в конфигурации кластера ClickHouse (config.xml).default
→ Название базы данных.events_local
→ Локальная таблица.rand()
→ Случайным образом выбирает шард для вставок. ✅ Запросы, отправленные вevents_distributed
, маршрутизируются на соответствующий шард.
3. Как распределённые таблицы обрабатывают запросы
✅ Чтение данных (SELECT):
SELECT COUNT(*) FROM events_distributed;
Запрос выполняется параллельно на всех шардах. ClickHouse объединяет результаты перед возвращением.
✅ Вставка данных (INSERT):
INSERT INTO events_distributed VALUES (1, now(), 1001);
Данные вставляются в один шард (основано на функции rand()).
🔹 Альтернатива: Распределение на основе хэша Вместо rand()
, можно распределить данные на основе столбца:
CREATE TABLE events_distributed
ENGINE = Distributed(my_cluster, default, events_local, cityHash64(user_id));
✅ Обеспечивает, чтобы один и тот же пользователь всегда попадал на один и тот же шард.
4. Оптимизация запросов с распределёнными таблицами
✅ Выполнение запросов на конкретном шарде: Можно ограничить запросы конкретным шардом:
SELECT * FROM events_local ON CLUSTER my_cluster WHERE _shard_num = 1;
✅ Полезно для диагностики данных, специфичных для шарда.
✅ Включение prefer_localhost_replica
(Быстрее запросы): Измените настройки кластера, чтобы предпочитать запросы к локальной реплике:
SET prefer_localhost_replica = 1;
✅ Уменьшает задержку при сетевых запросах между узлами.
5. Обработка дисбаланса данных в распределённых таблицах
🚨 Проблема: При добавлении нового узла старые данные остаются на существующих узлах. ✅ Решение: Перераспределение данных вручную.
Как перераспределить данные по шардом:
- Вставьте данные через распределённую таблицу:
INSERT INTO events_distributed SELECT * FROM events_distributed;
- Удалите старые данные с исходных шардов:
ALTER TABLE events_local DELETE WHERE 1;
✅ Обеспечивает равномерное распределение данных по всем узлам.
6. Итоги: Как работают распределённые таблицы
Особенность | Описание |
---|---|
Служит маршрутизатором запросов | Не хранит данные, только перенаправляет запросы |
Поддерживает шардирование | Запросы выполняются параллельно на нескольких узлах |
Автоматическая балансировка нагрузки | Чтение распределяется автоматически, запись может быть хешированной |
Обрабатывает отказоустойчивость | Запросы перенаправляются на доступные реплики в случае сбоя |
Перераспределение данных вручную | Старые данные не перераспределяются автоматически при добавлении нового узла |
🚀 Основной вывод: Распределённые таблицы обеспечивают масштабируемость, балансировку нагрузки и отказоустойчивость, что делает ClickHouse мощным выбором для анализа больших данных.