Перейти к основному содержимому
Версия: 2.0.x

Bucketing

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


Сравнительная таблица

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

Hash Bucketing

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

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

Требования

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

Сильные стороны

  • Локальность запросов — выборочные фильтры и JOIN затрагивают меньше tablet.
  • Colocate JOIN — таблицы фактов/измерений могут использовать общие хеш-ключи для высокоскоростных JOIN.
  • Предсказуемая структура — строки с одним и тем же ключом всегда находятся вместе.
  • Локальная агрегация и bucket-shuffle JOIN — идентичная хеш-структура между партициями позволяет локальную агрегацию и снижает затраты на перемешивание данных при больших JOIN.

Слабые стороны

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

Пример: JOIN измерений и фактов и отсечение tablet

-- Таблица фактов, партиционированная и с хеш-bucket по (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");

-- Таблица измерений с хеш-bucket по тому же ключу и количеству bucket, colocate с таблицей 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
SELECT sum(amount)
FROM sales
WHERE customer_id = 123

-- Selena может выполнить локальную агрегацию
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: Предикат customer_id WHERE customer_id = 123 позволяет отсечение bucket, позволяя запросу обращаться только к одному tablet, что снижает задержку и циклы CPU, особенно для точечных запросов.
  • Локальная агрегация: когда ключ хеш-распределения является подмножеством ключа агрегации, Selena может обойти фазу агрегации с перемешиванием, снижая общие затраты.
  • Colocate JOIN: поскольку обе таблицы используют одинаковое количество bucket и ключ, каждый BE может объединить свою локальную пару tablet без сетевого перемешивания.

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

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

Random Bucketing

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

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

Сильные стороны

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

Слабые стороны

  • Нет отсечения bucket — каждый запрос сканирует все tablet в партиции.
  • Нет colocate JOIN — структура без ключей предотвращает локальность.
  • Ограничено таблицами Duplicate Key на сегодняшний день.

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

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

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

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