В распределённом аналитическом хранилище часто соединяют факты с измерениями по одному ключу. Как выбор клю...

В распределённом аналитическом хранилище часто соединяют факты с измерениями по одному ключу. Как выбор ключа распределения может уменьшить сетевой обмен при соединении?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Если таблицы распределить по одному и тому же ключу соединения, строки с одинаковым значением ключа попадут на одни и те же узлы. Такое совместное размещение данных позволяет выполнить соединение локально на узлах и не пересылать большие объёмы строк по сети. Однако выгода сохраняется только при приемлемом распределении данных: неравномерный ключ создаёт перегруженные узлы.

Исторический контекст

Массивно-параллельные аналитические системы разделяют данные между узлами, чтобы выполнять сканирование и вычисления параллельно. Изначально главным ограничением становилась не только вычислительная мощность, но и стоимость обмена данными между узлами.

При обычном распределении таблиц строки, необходимые для одного соединения, могут находиться на разных узлах. Система вынуждена выполнять перераспределение или пересылку данных перед соединением, поэтому выбор физической схемы хранения стал частью проектирования аналитической модели.

Постановка проблемы

Пусть большая таблица фактов соединяется с измерением по идентификатору клиента. Если факты распределены по идентификатору заказа, а измерение — по идентификатору клиента, совпадающие строки обычно расположены на разных узлах.

Тогда система должна переслать одну или обе стороны соединения. Это увеличивает сетевой трафик, задержку, нагрузку на память и риск того, что один узел станет узким местом. Простое совпадение названий столбцов недостаточно: важны одинаковый ключ распределения и совместимое правило его хеширования.

Подробное решение

При распределении по ключу система вычисляет функцию, часто хеш, и по её результату выбирает узел. Если таблицы фактов и измерений распределены по одному ключу, например по идентификатору клиента, строки с одинаковым идентификатором клиента направляются на один узел.

Соединение по этому ключу можно выполнить локально на каждом узле. Система обрабатывает только свою часть данных и не обязана перед каждой операцией пересобирать таблицы на общей площадке. Это называют колокацией или совместным размещением данных.

Такой выбор особенно полезен, когда соединение выполняется часто, таблица фактов велика, а ключ имеет высокую кардинальность и относительно равномерное распределение. Малую таблицу измерений иногда выгоднее полностью реплицировать на каждый узел: тогда сетевой обмен для соединения также исчезает, но возрастает стоимость хранения и обновления копий.

Ключ должен соответствовать реальным шаблонам запросов. Распределение по слишком малому числу значений создаёт перекос данных: один узел получает непропорционально большой объём строк и ограничивает скорость всей параллельной операции. Распределение по случайному техническому идентификатору может хорошо балансировать объём, но не поможет соединениям по клиенту.

Колокация не устраняет все расходы. Запросы с другими ключами могут по-прежнему требовать перераспределения, а изменение ключа распределения обычно требует перемещения или перезаписи большого объёма данных. Кроме того, нужно учитывать размер таблиц, частоту соединений, кардинальность ключа и возможность изменения бизнес-нагрузки.

Ситуация из практики

В витрине продаж таблица фактов содержит несколько миллиардов строк, а отчёты регулярно соединяют её с измерением клиентов по идентификатору клиента. Изначально факты распределили по идентификатору продажи, а измерение — по идентификатору клиента. Отчёты выполняли дорогое перераспределение фактов перед каждым соединением.

Рассматривались два варианта. Репликация измерения была простой и эффективной для небольшой таблицы, но требовала обновления копий и становилась неудобной при росте измерения. Перераспределение данных во время каждого запроса не требовало изменения хранения, но сохраняло высокий сетевой расход.

Выбрали распределение фактов и измерения по идентификатору клиента, предварительно проверив равномерность ключа и наличие запросов по другим измерениям. Основное соединение стало локальным, сетевой обмен и задержка отчётов снизились. Для редких соединений по другим ключам сохранили возможность временного перераспределения, не пытаясь оптимизировать один шаблон за счёт всех остальных.

Что кандидаты часто упускают

1. Дополнительный вопрос: Достаточно ли распределить обе таблицы по одному столбцу, чтобы соединение всегда выполнялось локально?

Ответ: Нет. Помимо одинакового логического ключа, должны совпадать правила распределения, типы и преобразования значений. Если одна таблица распределена по хешу исходного значения, а другая — по преобразованному или составному ключу, одинаковые значения могут оказаться на разных узлах. Также оптимизатор может выбрать другой план, если таблица мала и её дешевле реплицировать.

2. Дополнительный вопрос: Что произойдёт, если ключ соединения имеет очень неравномерное распределение?

Ответ: Возникнет перекос данных. Строки популярных клиентов или других часто повторяющихся значений сосредоточатся на отдельных узлах, тогда как остальные узлы завершат работу раньше. Время запроса будет определяться самым загруженным узлом, поэтому формальная колокация не гарантирует хорошую производительность. Возможные меры — выбрать другой ключ, использовать составное распределение, реплицировать небольшую таблицу или применять специальные стратегии для часто встречающихся значений.

3. Дополнительный вопрос: Когда репликация измерения предпочтительнее его распределения по ключу соединения?

Ответ: Репликация обычно предпочтительнее, когда измерение достаточно мало, обновляется не слишком часто и используется во многих соединениях с разными ключами. Каждый узел получает локальную копию и не требует сетевого обмена для чтения измерения. Компромисс состоит в дополнительных расходах на хранение, распространение обновлений и поддержание согласованности копий; для большой или часто изменяемой таблицы распределение по ключу может быть безопаснее.