Принципы движка хранения


1 Обзор MARS2

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

1.1 Внутренние принципы

Таблица MARS2 аналогична MARS3 и также использует структуру LSM-дерева для хранения.

Схематическое представление внутреннего устройства MARS2:

Далее мы пошагово проанализируем эту схему на концептуальном уровне.

1.1.1 Ключ сортировки

  • В MARS2 данные хранятся в упорядоченном виде. При создании таблицы необходимо определить порядок сортировки путем создания индекса. Поля, участвующие в этом порядке, называются ключами сортировки.
  • Ключ сортировки может быть задан только один раз и не может быть изменен или удален.
  • Для максимального повышения производительности, обусловленного использованием упорядоченности, рекомендуется выбирать в качестве ключа сортировки поля, часто используемые в запросах и обладающие хорошими фильтрующими свойствами. Например, в таблице мониторинга устройств ключами сортировки могут быть временная метка события и идентификатор устройства.
  • Если ключ сортировки имеет текстовый тип и допускает сортировку по байтовому порядку, использование COLLATE C в этом столбце ускорит процесс сортировки.

1.1.2 Run и метаданные

  • В соответствии с ключом сортировки данные в MARS2 хранятся упорядоченно; непрерывный и упорядоченный фрагмент данных называется Run.
  • Для возможности определения местоположения Run записываются сведения о его расположении — так называемые метаданные Run.
  • Метаданные также содержат минимальное и максимальное значения Run, что позволяет фильтровать данные при выполнении запросов.
  • При вставке данных сначала происходит сортировка в памяти, поэтому размер Run зависит от объема памяти, доступной для сортировки.

1.1.3 Слияние

  • Если диапазоны данных в Run перекрываются, это приводит к усилению чтения и снижению эффективности запросов. Поэтому, когда количество Run на диске превышает определенный порог, MARS2 загружает несколько Run из диска в память, сортирует их и выводит как один Run. Этот процесс называется слиянием (merge).
  • Во время слияния данные остаются доступными для чтения и записи:
    • При чтении данных читаются только входные файлы слияния;
    • При записи данных процесс слияния не учитывает новые данные;
    • Чтение, запись и слияние не блокируют друг друга.

1.1.4 Уровни

  • Для обеспечения схожести размеров входных файлов слияния (избегая слияния крупных файлов с мелкими) Run организованы в уровни: L0, L1, L2.
  • Когда размер данных, полученных в результате слияния, превышает определенный порог, они переходят на более высокий уровень. Процесс выглядит следующим образом:
      1. Новые данные размещаются в L0. Когда количество Run достигает определенного порога (настраиваемое значение, см. параметр конфигурации mars2_automerge_threshold), запускается слияние L0, объединяющее все Run L0 в один Run.
      1. Если размер результирующего Run превышает 25 МБ (настраиваемый параметр, см. level0_upgrade_size), он переводится в L1.
      1. Если суммарный размер Run в L1 превышает 1000 МБ (настраиваемый параметр, см. level1_upgrade_size), запускается слияние, объединяющее все Run L1 в один Run.
      1. Если размер результирующего Run превышает 1000 МБ (настраиваемый параметр, см. level1_upgrade_size), он переводится в L2.
      1. Run, достигшие уровня L2, больше не сливаются.

1.1.5 Хранение по столбцам

  • MARS2 использует столбцовое хранение данных. При доступе к диску загружаются только те столбцы, которые требуются, что снижает I/O-нагрузку.
  • Однородность типов данных в одном столбце упрощает сжатие и экономит место на диске.
  • Кроме того, столбцовое хранение хорошо подходит для векторизованного выполнения, что значительно ускоряет обработку запросов. Подробнее см. Векторизованный движок выполнения.

1.1.6 Фильтрация MINMAX

  • Метаданные Run, описанные выше, содержат минимальные и максимальные значения для фильтрации при выполнении запросов.
  • Поскольку фильтрация осуществляется на основе метаданных, сами данные не загружаются, что снижает I/O-накладные расходы по сравнению с последовательным сканированием (сначала чтение данных, затем фильтрация) и ускоряет фильтрацию.
  • При создании таблицы в MARS2 минимальные и максимальные значения по умолчанию не записываются — необходимо явно объявить их использование.

Сначала создайте расширение matrixts:

=# CREATE EXTENSION matrixts ;

Явное объявление записи минимальных и максимальных значений.

=# CREATE TABLE metrics (
    ts              timestamp   ENCODING(minmax),
    dev_id          bigint      ENCODING(minmax),
    power           float,
    speed           float,
    message         text
) USING MARS2;

Создание индекса mars2_btree.

=# CREATE INDEX ON metrics
USING mars2_btree (ts, dev_id);
  • Минимальные и максимальные значения могут быть определены как для ключей сортировки, так и для других столбцов. Эффект наиболее выражен при определении для ключей сортировки. В выражениях MINMAX может быть записан как в верхнем, так и в нижнем регистре.
  • Кроме того, MINMAX может быть определен для максимум 32 столбцов.

1.1.7 Btree-индекс MARS2

  • Помимо MINMAX, MARS2 имеет встроенный индекс (создаваемый при создании таблицы).
  • В настоящее время можно определить только один индекс, то есть только один глобальный порядок сортировки.
  • В отличие от обычного Btree-индекса, Btree-индекс MARS2:
    • является разреженным, поэтому занимает меньше места;
    • поскольку данные сами по себе упорядочены, индексные сканирования не генерируют случайные I/O-операции.

1.1.8 Сжатие

Как в MARS3.

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

1.1.9 Запись данных

  • Данные записываются в память через INSERT, после чего проходят через указанные процессы для формирования Run.
  • Если объем вставляемых данных велик и превышает объем памяти для сортировки, генерируется несколько Run.
  • Размер памяти для сортировки настраивается — подробности см. в разделе «1.2.2 Параметры конфигурации».

1.1.10 Обновление и удаление

  • MARS2 в настоящее время не поддерживает операции обновления и удаления.
  • Операцию обновления можно заменить режимом Unique.
  • Операцию удаления можно выполнить только путем удаления или TRUNCATE партиционированной таблицы.

1.2 Использование MARS2

1.2.1 Создание таблицы MARS2

При условии, что расширение matrixts уже создано, простейший способ создания таблицы — добавить к оператору CREATE TABLE ключевое слово USING и создать индекс. Расширенные примеры см. в разделе Лучшие практики проектирования таблиц.

=# CREATE TABLE metrics (
    ts              timestamp,
    dev_id          bigint,
    power           float,
    speed           float,
    message         text
) USING MARS2;

=# CREATE INDEX ON metrics
USING mars2_btree (ts, dev_id);

1.2.2 Параметры конфигурации

Примечание!
Следующие параметры уровня таблицы — это параметры, которые можно настраивать только с помощью ключевого слова WITH при создании таблицы. Они применимы к отдельным таблицам и не могут быть изменены после настройки. Глобальные параметры — это параметры, которые можно настраивать на уровне сессии или системы; для вступления в силу изменений на уровне системы требуется выполнение mxstop -u. Подробнее см. Параметры конфигурации таблиц.

Следующие параметры управляют слиянием (Merge), и их влияние на процесс описано в разделе «Уровни» выше.

Параметры управления слиянием Единицы Значение по умолчанию Диапазон значений Описание
mars2_automerge_threshold run 32 10 - 2048 Управляет количеством Run, при превышении которого запускается слияние в L0 для всех таблиц MARS2. Это глобальный параметр. Для индивидуальной настройки для отдельной таблицы используйте параметр таблицы level0_merge_threshold.
level0_merge_threshold run 32 1 - 2048 Управляет количеством Run, при превышении которого запускается слияние. Параметр уровня таблицы.
level0_upgrade_size MB 25 1 - 10000 Управляет размером перехода L0 → L1 для отдельной таблицы. Если размер результирующего Run после слияния L0 превышает этот порог, он переводится в L1. Параметр уровня таблицы.
level1_upgrade_size MB 1000 1 - 10000 Управляет размером перехода L1 → L2 для отдельной таблицы. Если размер результирующего Run после слияния L1 превышает этот порог, он переводится в L2. Параметр уровня таблицы.
  • Если вставляется мало данных (каждая вставка соответствует одному Run), слияние будет запускаться слишком часто, что неэффективно. В этом случае можно увеличить параметры mars2_automerge_threshold / level0_merge_threshold, чтобы увеличить количество входных Run в слияние и снизить частоту слияний.
  • Если результат слияния L0/L1 не достигает порога для перехода в следующий уровень, в следующем слиянии он будет объединен с новыми Run, что приведет к усилению записи. Чтобы избежать этого, можно уменьшить level0_upgrade_size / level1_upgrade_size, чтобы ускорить переход на следующий уровень.

Следующие параметры управляют сжатием и влияют на его эффективность. При слишком низких значениях эффект сжатия может быть слабым; при слишком высоких — увеличивается потребление памяти.

Параметры управления сжатием Единицы Значение по умолчанию Диапазон значений Описание
compress_threshold Tuple 1200 1 - 100000 Порог сжатия. Определяет количество кортежей (tuples), при превышении которого сжимаются данные в одной таблице. Это максимальное количество кортежей, сжимаемых в единице. Параметр уровня таблицы.

Следующие параметры управляют памятью. Эти параметры определяют объем памяти для сортировки при вставке данных. При вставке в несколько партиционированных таблиц каждая таблица выделяет память, указанную в mars2_sort_mem_core; если недостаточно — память расширяется, но общий объем не превышает mars2_sort_mem.

Параметры памяти для сортировки Единицы Значение по умолчанию Диапазон значений Описание
mars2_sort_mem KB 2097152KB (2 ГБ) 128KB - 2147483647KB (~2048 ГБ) Управляет объемом памяти для сортировки при каждой отдельной вставке. Если целевая таблица является партиционированной, все партиции делят этот объем. Глобальный параметр.
mars2_sort_mem_core KB 16384KB (16 МБ) 128KB - 2147483647KB (~2048 ГБ) Управляет минимальным объемом памяти, выделяемым для каждой отдельной партиции. Глобальный параметр.

Примеры параметров таблицы:

=# CREATE TABLE metrics (
    ts              timestamp,
    dev_id          bigint,
    power           float,
    speed           float,
    message         text
) 
USING MARS2
WITH (compress_threshold=1200,level0_merge_threshold=32);

=# CREATE INDEX ON metrics
USING mars2_btree (ts, dev_id);

Пример изменения глобальных параметров на уровне сессии:

=# SET mars2_sort_mem TO 2097152;

Пример изменения глобальных параметров на уровне системы:

=# gpconfig -c mars2_sort_mem -v 2097152
=# \q
$ mxstop -u

2 Обзор HEAP

HEAP — это движок хранения по умолчанию в YMatrix, также известный как heap-хранение, унаследованный от PostgreSQL. Поддерживает только строковое хранение, не поддерживает столбцовое хранение и сжатие, но поддерживает партиционированные таблицы. Реализован на основе механизма MVCC и подходит для сценариев с большим количеством операций обновления и удаления.

2.1 Использование механизма MVCC

Механизм MVCC (Multiversion Concurrency Control), или многоверсионное управление, в основном применяется для обновления, изменения и удаления данных.
При многоверсионном управлении обновления и удаления не обязательно изменяют исходные данные напрямую — вместо этого создается новая версия, старая версия помечается как недействительная, а новые данные добавляются в новую версию. Таким образом, данные могут иметь несколько версий, каждая из которых содержит информацию о версии, а исторические версии сохраняются.
Под влиянием механизма MVCC при обработке операций обновления и удаления в таблице HEAP данные физически не удаляются — вместо этого старые данные блокируются на основе информации о версии (контролируется видимость данных). Следовательно, при частых обновлениях и удалениях физический объем, занимаемый таблицей HEAP, будет постоянно расти, и необходимо регулярно и планово очищать устаревшие данные.

2.2 Использование HEAP

Для создания таблицы HEAP в YMatrix можно использовать следующий SQL-запрос:

=# CREATE TABLE disk_heap(
    time timestamp with time zone,
    tag_id int,
    read float,
    write float
)
DISTRIBUTED BY (tag_id);

3 Обзор AO

Таблицы с движками хранения AOCO и AORO объединяются под общим названием AO (Append-Optimized) — таблицы с оптимизацией для добавления. Они поддерживают операции вставки, обновления и удаления, а также сжатие.
AORO поддерживает строковое хранение, AOCO — столбцовое.
AO-таблицы существенно отличаются от HEAP-таблиц как логической, так и физической структурой. Как упоминалось ранее, HEAP-таблицы используют механизм MVCC для контроля видимости данных после операций обновления и удаления, тогда как AO-таблицы используют дополнительную битовую карту. Содержимое этой карты указывает, какие данные в AO-таблице являются видимыми.
Для AO-таблиц с большим количеством операций обновления и удаления также требуется регулярная плановая очистка старых данных. Однако в AO-таблицах инструмент очистки vacuumcum должен сбрасывать битовую карту и сжимать физические файлы, поэтому он обычно работает медленнее, чем в HEAP.

Примечание!
Подробности о движках хранения MARS2, HEAP и AO см. в разделе Лучшие практики проектирования таблиц