Перейти к основному содержимому

Bucketing

Краткое руководство по выбору между Hash Bucketing и Random Bucketing в Selena, включая их механизмы, компромиссы и рекомендуемые случаи использования.


Быстрое сравнение

АспектHash BucketingRandom Bucketing
ПримерDISTRIBUTED BY HASH(id) BUCKETS 16DISTRIBUTED BY RANDOM
Объявление ключаТребуется HASH(col1, …)Отсутствует – строки назначаются по принципу round‑robin
Начальное количество bucket при пропускеАвтоматически выбирается при CREATE, затем фиксируетсяАвтоматически выбирается при CREATE; может расти при установке bucket_size
Разделение / сжатие tabletРучное ALTER … BUCKETSАвтоматическое разделение ⇢ только рост (≥ v3.2)
Устойчивость к перекосуЗависит от кардинальности ключаВысокая – равномерная по дизайну
Bucket pruning✅ (фильтры, соединения)🚫 (полное сканирование tablet)
Colocate joins🚫
Local aggregation / bucket-shuffle joins🚫
Поддерживаемые типы таблицВсеТолько таблицы Duplicate Key

Hash Bucketing

Как это работает

Строки назначаются tablet путем хеширования одного или нескольких столбцов. Количество tablet фиксируется после создания, если не изменяется вручную.

Требования

  • Необходимо заранее выбрать стабильный, равномерно распределенный ключ с высокой кардинальностью. Кардинальность должна быть обычно в 1000 раз больше количества BE узлов, чтобы предотвратить перекос данных между hash bucket.
  • Изначально выберите подходящий размер bucket, в идеале от 1 до 10 ГБ.

Преимущества

  • Локальность запросов – селективные фильтры и соединения затрагивают меньше tablet.
  • Colocate joins – таблицы фактов/измерений могут использовать общие hash ключи для высокоскоростных соединений.
  • Предсказуемая структура – строки с одинаковым ключом всегда располагаются вместе.
  • Local aggregation & bucket‑shuffle joins – идентичная hash структура между партициями обеспечивает локальную агрегацию и снижает затраты на перемешивание данных для больших соединений

Недостатки

  • Уязвим к горячим tablet при перекосе распределения данных.
  • Количество tablet статично; масштабирование требует DDL обслуживания.
  • Недостаточное количество tablet может негативно повлиять на загрузку данных, сжатие данных и параллелизм выполнения запросов.
  • Чрезмерное использование tablet увеличит объем метаданных.

Пример: Соединение измерений и фактов и Tablet Pruning

-- Таблица фактов, разделенная и hash‑bucketed по (customer_id)
CREATE TABLE sales (
sale_id bigint,
customer_id int,
sale_date date,
amount decimal(10,2)
) ENGINE = OLAP
DISTRIBUTED BY HASH(customer_id) BUCKETS 48
PARTITION BY date_trunc('DAY', sale_date)
PROPERTIES ("colocate_with" = "group1");

-- Таблица измерений hash‑bucketed по тому же ключу и количеству bucket, размещенная с таблицей sales
CREATE TABLE customers (
customer_id int,
region varchar(32),
status tinyint
) ENGINE = OLAP
DISTRIBUTED BY HASH(customer_id) BUCKETS 48
PROPERTIES ("colocate_with" = "group1");


-- Selena может выполнить tablet pruning
SELECT sum(amount)
FROM sales
WHERE customer_id = 123

-- Selena может выполнить local aggregation
SELECT customer_id, sum(amount) AS total_amount
FROM sales
GROUP BY customer_id
ORDER BY total_amount DESC LIMIT 100;

-- Selena может выполнить colocate join
SELECT c.region, sum(s.amount)
FROM sales s JOIN customers c USING (customer_id)
WHERE s.sale_date BETWEEN '2025-01-01' AND '2025-01-31'
GROUP BY c.region;

Что вы получаете от этого примера?

  • Tablet pruning: предикат customer_id WHERE customer_id = 123 обеспечивает bucket pruning, позволяя запросу обращаться только к одному tablet, что снижает задержку и циклы CPU, особенно для точечных поисков.
  • Local aggregation: когда ключ hash распределения является подмножеством ключа агрегации, Selena может обойти фазу shuffle агрегации, снижая общую стоимость.
  • Colocated join: поскольку обе таблицы используют одинаковое количество bucket и ключ, каждый BE может соединить свою локальную пару tablet без сетевого перемешивания.

Когда использовать

  • Стабильные схемы с хорошо известными ключами фильтрации/соединения распределения.
  • Рабочие нагрузки хранилищ данных, которые выигрывают от bucket pruning.
  • Вам нужна какая-то специфическая оптимизация, такая как colocate join/bucket shuffle join/local aggregation
  • Вы используете таблицы Aggregate/Primary Key.

Random Bucketing

Как это работает

Строки назначаются по принципу round‑robin; ключ не указывается. С PROPERTIES ("bucket_size"="<bytes>"), Selena динамически разделяет tablet по мере роста партиций (v3.2+).

Преимущества

  • Нулевой технический долг – никаких ключей, никаких вычислений bucket.
  • Защита от перекоса записи – равномерная нагрузка на диски и BE.
  • Эластичный рост – разделение tablet поддерживает быструю загрузку по мере роста данных или кластера.

Недостатки

  • Отсутствие bucket pruning – каждый запрос сканирует все tablet в партиции.
  • Отсутствие colocated joins – структура без ключей препятствует локальности.
  • Ограничено таблицами Duplicate Key на сегодняшний день.

Когда использовать

  • Таблицы логов/событий или мультитенантных SaaS, где ключи изменяются или перекашиваются.
  • Конвейеры с интенсивной записью, где критична равномерная пропускная способность загрузки.

Операционные рекомендации

  • Выберите размер bucket (например, 1 ГиБ) для random bucketing, чтобы включить автоматическое разделение.
  • Для hash bucketing отслеживайте размер tablet; перераспределяйте до того, как tablet превысят 5–10 ГиБ