Таблицы Primary Key
Таблица Primary Key использует новый движок хранения, разработанный Selena. Его основное преимущество заключается в поддержке обновлений данных в режиме реального времени при сохранении эффективной производительности для сложных ad-hoc запросов. В аналитике бизнеса в реальном времени принятие решений может выиграть от использования таблиц Primary Key, которые используют самые свежие данные для анализа результатов в реальном времени, что может смягчить задержку данных в анализе данных. Однако первичный ключ — это не бесплатный обед. При неправильном использовании он может привести к ненужной трате ресурсов.
Поэтому в этом разделе мы расскажем вам, как более эффек тивно использовать модель первичного ключа для достижения желаемых результатов.
Выбор индекса Primary Key
Первичный индекс является наиболее критическим компонентом в таблице Primary Key. Индекс первичного ключа используется для хранения сопоставления между значениями первичного ключа и расположениями строк данных, идентифицируемых значениями первичного ключа.
В настоящее время мы поддерживаем три типа индекса первичного ключа:
- Полностью в памяти индекс первичного ключа.
PROPERTIES (
"enable_persistent_index" = "false"
);
- Persistent индекс первичного ключа на основе локального диска.
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "LOCAL"
);
- Cloud native persistent индекс первичного ключа.
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE"
);
Мы НЕ рекомендуем использовать индексирование в памяти, так как это мож ет привести к значительной трате ресурсов памяти.
Если вы используете shared-data (elastic) cluster Selena, мы рекомендуем выбрать cloud-native persistent индекс первичного ключа. В отличие от локального дискового persistent индекса первичного ключа, он хранит полные данные индекса в удаленном объектном хранилище, используя локальные диски только в качестве кеша. По сравнению с локальным дисковым persistent индексом первичного ключа, его преимущества включают:
- Отсутствие зависимости от емкости локального диска.
- Отсутствие необходимости перестраивать индексы после ребалансировки data shard'ов.
Выбор первичного ключа
Первичный ключ обычно не помогает ускорить запросы. Вы можете указать столбец, отличный от первичного ключа, в качестве ключа сортировки, используя предложение ORDER BY, чтобы ускорить запросы. Поэтому при выборе первичного ключа вам нужно учитывать только уникальность во время процессов импорта и об новления данных.
Чем больше первичный ключ, тем больше памяти, I/O и других ресурсов он потребляет. Поэтому обычно рекомендуется избегать выбора слишком большого количества или слишком больших столбцов в качестве первичного ключа. Максимальный размер первичного ключа по умолчанию составляет 128 байт, управляется параметром primary_key_limit_size в be.conf.
Вы можете увеличить primary_key_limit_size, чтобы выбрать больший первичный ключ, но имейте в виду, что это приведет к более высокому потреблению ресурсов.
Сколько места для хранения и памяти займет persistent индекс?
Формула стоимости места для хранения
(key size + 8 bytes) * row count * 50%
50% — это оценочная эффективность сжатия, фактический эффект сжатия зависит от самих данных.
Формула стоимости памяти
min(l0_max_mem_usage * tablet cnt, update_memory_limit_percent * BE process memory);
Использование памяти
Память, используемая таблицей Primary Key, может отслеживаться через mem_tracker:
// Просмотр общей статистики памяти
http://be_ip:be_http_port/mem_tracker
// Просмотр статистики памяти таблицы primary key
http://be_ip:be_http_port/mem_tracker?type=update
// Просмотр статистики памяти таблицы primary key с более подробной информацией
http://be_ip:be_http_port/mem_tracker?type=update&upper_level=4
Элемент update в mem_tracker записывает всю память, используемую таблицей Primary Key, такую как индекс первичного ключа, delete vector и так далее.
Вы также можете отслеживать этот элемент update через сервис мониторинга метрик. Например, в Grafana вы можете проверить элемент update через (элемент в красной рамке):

Подробнее о мониторинге и оповещениях с Prometheus и Grafana: https://docs.selena.io/docs/administration/management/monitoring/Monitor_and_Alert/
Если вы чувствительны к использованию памяти и хотите снизить потребление памяти во время процесса импорта в таблицу PK, вы можете достичь этого с помощью следующей конфигурации:
be.conf
l0_max_mem_usage = (некоторое значение меньше 104857600, по умолчанию 104857600)
skip_pk_preload = true
// Shared-nothing cluster
transaction_apply_worker_count = (некоторое значение меньше количества ядер cpu, по умолчанию количество ядер cpu)
// Shared-data cluster
transaction_publish_version_worker_count = (некоторое значение меньше количества ядер cpu, по умолчанию количество ядер cpu)
l0_max_mem_usage контролирует максимальное использование памяти persistent индекса первичного ключа на tablet. transaction_apply_worker_count и transaction_publish_version_worker_count оба контролируют максимальное количество потоков, которые могут использоваться для обработки upsert и delete в таблице primary key.
Но вам нужно помнить, что уменьшение l0_max_mem_usage может увеличить давление I/O, в то время как уменьшение transaction_apply_worker_count или transaction_publish_version_worker_count может замедлить прием данных.