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

Merge-on-Write

Merge-on-write и merge-on-read — два варианта реализации хранения данных для модели Unique Key. Оба обеспечивают уникальность значений в столбцах Key и возвращают одинаковые результаты запросов, но устраняют дубликаты Key на разных этапах, что влияет на производительность чтения и записи. Merge-on-write используется по умолчанию и лучше всего подходит для большинства рабочих нагрузок.

Сравнение​

РеализацияМомент слиянияПроизводительность записиПроизводительность запросовСценарии применения
Merge-on-write (по умолчанию)При записиСредняяВысокаяБольшинство сценариев, требующих баланса между производительностью запросов и записи
Merge-on-readПри выполнении запроса или компакцииВысокаяБолее низкаяСценарии с интенсивной записью и редким чтением

Как работает Merge-on-Write​

При использовании merge-on-write Doris устраняет дубликаты Key во время записи данных. Для каждой поступающей строки система проверяет, существует ли уже такой Key, и помечает предыдущую версию как удалённую в битовой карте удалений. Запросы используют эту карту, чтобы пропускать помеченные строки и читать только последнюю версию. Впоследствии компакция удаляет эти строки с диска.

Поскольку дубликаты устраняются при записи:

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

Дополнительные затраты приходятся на запись. При каждой операции upsert выполняется поиск по первичному ключу, чтобы найти и пометить предыдущую версию, что увеличивает накладные расходы на запись по сравнению с merge-on-read. Для большинства рабочих нагрузок такой компромисс оправдан, поэтому merge-on-write используется по умолчанию.

Как работает Merge-on-Read​

При использовании merge-on-read операции записи только добавляют данные. Doris сохраняет все версии каждого Key и объединяет их при выполнении запроса или во время компакции, возвращая последнюю версию.

Поскольку дубликаты устраняются при чтении:

  • Операции записи требуют мало ресурсов, поскольку поиск по первичному ключу не выполняется.
  • Каждый запрос должен объединять версии каждого Key, а Doris не может применять фильтры на уровне хранения, поэтому запросы выполняются медленнее.
  • Задержка выполнения запросов растёт по мере накопления версий между компакциями.

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

Выбор между реализациями​

  • Используйте merge-on-write (по умолчанию) для большинства рабочих нагрузок, включая обновления в реальном времени, синхронизацию измерений и любые сценарии, где важна производительность запросов. Эта реализация также позволяет использовать такие возможности, как частичное обновление столбцов.
  • Используйте merge-on-read только тогда, когда операций записи значительно больше, чем операций чтения, и требуется свести накладные расходы на запись к минимуму.

Реализация задаётся при создании таблицы и не может быть изменена впоследствии посредством изменения схемы, поэтому определитесь с выбором до создания таблицы.

Включение каждой реализации​

Реализация определяется свойством таблицы enable_unique_key_merge_on_write.

Merge-on-write (по умолчанию):

CREATE TABLE IF NOT EXISTS example_tbl_unique
(
user_id LARGEINT NOT NULL,
user_name VARCHAR(50) NOT NULL,
city VARCHAR(20),
age SMALLINT,
sex TINYINT
)
UNIQUE KEY(user_id, user_name)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES (
"enable_unique_key_merge_on_write" = "true"
);

Merge-on-read (задайте свойству значение false):

CREATE TABLE IF NOT EXISTS example_tbl_unique
(
user_id LARGEINT NOT NULL,
user_name VARCHAR(50) NOT NULL,
city VARCHAR(20),
age SMALLINT,
sex TINYINT
)
UNIQUE KEY(user_id, user_name)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES (
"enable_unique_key_merge_on_write" = "false"
);

Возможности, для которых требуется Merge-on-Write​

Частичное обновление столбцов требует merge-on-write: оно позволяет обновлять часть столбцов без перезаписи всей строки.