Что такое дистрибуция данных в ClickHouse
Что проверяют
Понимаете ли вы, как запрос превращается в работу на нескольких машинах и где в этой схеме вас ждёт боль. Вопрос задают перед проектированием кластера: от ключа шардирования зависит, останутся ли запросы дешёвыми или каждый превратится в пересылку данных по сети.
Как отвечать
Разложите на слои. Данные лежат в локальных таблицах семейства MergeTree на каждом узле. Поверх них создаётся таблица Distributed, сама она ничего не хранит: знает кластер, локальную таблицу и ключ шардирования, рассылает подзапросы по шардам и сливает ответы. Отказоустойчивость обеспечивает другой механизм, реплицируемые таблицы с координацией через Keeper.
Ключ шардирования это выражение, обычно хэш от идентификатора сущности. Выбирают по двум критериям: равномерность, чтобы не получить перекошенный шард, и локальность, чтобы строки, которые соединяются и группируются вместе, лежали на одном узле.
Писать лучше прямо в локальные таблицы, раскладывая нагрузку самому. Вставка через Distributed складывает пачки во временный каталог и отправляет их асинхронно, то есть успешный ответ на вставку ещё не значит, что данные видны в запросе.
Обязательно скажите про подзапросы: обычный IN внутри распределённого запроса выполняется на каждом шарде по его собственным данным, и результат тихо получается неверным. Для таких случаев есть GLOBAL IN и GLOBAL JOIN, которые считают правую часть один раз и рассылают её.
Где спотыкаются
Обещают лёгкое масштабирование добавлением узла. Автоматической перебалансировки нет: новый шард получит только новые данные, а перераспределение старых это отдельная миграция с перезаливкой.
Берут ключом случайное значение или дату. Случайное даёт ровную заливку и дорогие соединения: связанные строки размазаны по кластеру. Дата собирает весь свежий поток в один шард, и он захлёбывается, пока остальные простаивают.
Путают шардирование с репликацией и на этом получают дубли. Реплики это копии одного шарда ради надёжности, шарды это разные части данных ради объёма и скорости. Если в описании кластера не сказано, что запись идёт в одну реплику и дальше расходится репликацией, таблица Distributed честно разошлёт копию в каждую, и строки задвоятся.