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: оно позволяет обновлять часть столбцов без перезаписи всей строки.