Логически Яндекс.Метрика имеет только один столбец с идентификатором высокой мощности, который служит главным ключом шардинга.
По умолчанию SELECTs из таблицы с Распределенным механизм запрашивает частичные результаты от одной реплики каждого шарда.
Если у вас около сотен серверов или более, достаточно много сетевых коммуникаций для запроса всех сегментов (вероятно, 1/2 или 1/3 всех серверов), что может привести к большей задержке, чем фактическое выполнение запроса.
Причиной такого поведения является то, что ClickHouse позволяет записывать данные непосредственно в шарды (в обход распределенного механизма и его настроенного ключа шардинга), а приложению, которое делает это, не обязательно соответствовать ключу шардинга распределенной таблицы (он может по-разному выбирать для распространения данных более равномерно или по любой другой причине).
Таким образом, идея этого двухуровневого шардинга состоит в том, чтобы разбить большой кластер на более мелкие подкластеры (по 10-20 серверов каждый) и сделать так, чтобы большинство запросов SELECT проходили через распределенные таблицы, которые настроены для подкластеров, таким образом делая меньше сетевое общение необходимо и снижает влияние возможных отставших.
Глобальные распределенные таблицы для всего большого кластера также настроены для некоторых специальных или обзорных запросов, но они не так часты и требуют меньших задержек.
Это по-прежнему оставляет свободу для приложения, которое записывает данные, чтобы произвольно балансировать их между сегментами, образующими подкластер (путем записи непосредственно в них).
Но для того, чтобы все это работало вместе, приложениям, которые записывают и читают данные, необходимо иметь согласованное отображение от того, какой идентификатор высокой мощности используется (CounterID в случае Metrica) на идентификатор подкластера и имена хостов, из которых он состоит. Metrica хранит это отображение в MySQL, но в других случаях что-то еще может выглядеть более подходящим.
Альтернативный подход заключается в использовании параметра «optimize_skip_unused_shards», который позволяет запросам SELECT, имеющим условие на ключ шардинга распределенной таблицы, пропускать шарды, в которых не должно быть данных. В нем вводится требование о том, что данные должны быть распределены между осколками точно так, как если бы они были записаны через эту распределенную таблицу, иначе в отчет не будут включены некоторые неуместные данные.