Практика использования решения хранения Heap + Mars1

В MatrixDB технология секционирования используется для комбинирования двух типов таблиц и разделения данных по временным меткам. Горячие данные сначала записываются в «горячую» секцию типа Heap. После подтверждения того, что доступ к данным больше не будет осуществляться и новые данные за предыдущие периоды поступать не будут, «горячая» секция Heap преобразуется в «холодную» секцию Mars.

Продолжительность временного интервала секции зависит от объёма данных. Например: если объём данных большой, размер секции должен быть небольшим — можно разделять по дням или часам; если объём данных мал, размер секции можно увеличить и делить по неделям или месяцам.

MatrixDB предоставляет пользовательские функции (UDF) для управления секциями, для начала необходимо установить соответствующие расширения:

CREATE EXTENSION matrixts;
CREATE EXTENSION mars;

Рассмотрим на примере записи объёма операций чтения и записи на диск использование горячего и холодного хранилищ:

1 Создание таблицы временных рядов

CREATE TABLE disk(
    time timestamp with time zone,
    tag_id int,
    read float,
    write float
)
Distributed by (tag_id)
Partition by range(time);

С помощью приведённого выше SQL-запроса создаётся таблица временных рядов, секционированная по временным меткам, с ключом распределения tag_id.

2 Создание шаблона секций

После создания таблицы временных рядов шаблон секций создаётся путём вызова функции build_timeseries_table, предоставляемой расширением mars:

SELECT mars.build_timeseries_table('disk','tagkey="tag_id", timekey="time", timebucket="1 day"');

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

Таблица шаблона секций не удаляется автоматически при использовании стандартной команды DROP и должна очищаться вручную. Если требуется удалить исходную таблицу, правильная последовательность действий следующая:

SELECT mars.destroy_timeseries_table('disk');
DROP TABLE disk;

3 Создание секции

После создания шаблона секций вызывается функция add_partition, предоставляемая расширением mars, чтобы создать секцию:

SELECT mars.add_partition('disk', '2021-04-01', '2021-05-01','1 day');

Как указано выше, данный SQL-запрос создаёт секцию с 1 апреля 2021 года по 1 мая 2021 года с временным интервалом в 1 день.

Для просмотра информации о секциях вызывается функция list_partition:

ymatrix=# SELECT * from mars.list_partition('disk');
                    relname                    | storage
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 heap_disk_20210401000000000_20210402000000000 | heap
 heap_disk_20210402000000000_20210403000000000 | heap
 heap_disk_20210403000000000_20210404000000000 | heap
 heap_disk_20210404000000000_20210405000000000 | heap
 heap_disk_20210405000000000_20210406000000000 | heap
 heap_disk_20210406000000000_20210407000000000 | heap
 heap_disk_20210407000000000_20210408000000000 | heap
 heap_disk_20210408000000000_20210409000000000 | heap
 heap_disk_20210409000000000_20210410000000000 | heap
 heap_disk_20210410000000000_20210411000000000 | heap
 heap_disk_20210411000000000_20210412000000000 | heap
 heap_disk_20210412000000000_20210413000000000 | heap
 heap_disk_20210413000000000_20210414000000000 | heap
 heap_disk_20210414000000000_20210415000000000 | heap
 heap_disk_20210415000000000_20210416000000000 | heap
 heap_disk_20210416000000000_20210417000000000 | heap
 heap_disk_20210417000000000_20210418000000000 | heap
 heap_disk_20210418000000000_20210419000000000 | heap
 heap_disk_20210419000000000_20210420000000000 | heap
 heap_disk_20210420000000000_20210421000000000 | heap
 heap_disk_20210421000000000_20210422000000000 | heap
 heap_disk_20210422000000000_20210423000000000 | heap
 heap_disk_20210423000000000_20210424000000000 | heap
 heap_disk_20210424000000000_20210425000000000 | heap
 heap_disk_20210425000000000_20210426000000000 | heap
 heap_disk_20210426000000000_20210427000000000 | heap
 heap_disk_20210427000000000_20210428000000000 | heap
 heap_disk_20210428000000000_20210429000000000 | heap
 heap_disk_20210429000000000_20210430000000000 | heap
 heap_disk_20210430000000000_20210501000000000 | heap
(30 rows)

Как показано в SQL-запросе выше, отображаются все подтаблицы секций, входящие в таблицу disk, включая имена подтаблиц и типы хранения.

4 Запись данных временных рядов

insert into disk values(now(), ...., ..., ...);

Так как таблица секционирована по времени, достаточно просто вставлять данные в основную таблицу — они автоматически попадут в соответствующую секцию.

5 Замена секций

После завершения сбора данных временных рядов за 1 апреля становится ясно, что новые данные за этот день больше поступать не будут. Секция за 1 апреля должна быть переведена из горячей (Heap) в холодную (Mars).

Расширение Mars предоставляет функцию compress_partition, предназначенную для преобразования секций:

ymatrix=# select mars.compress_partition('heap_disk_20210401000000000_20210402000000000');
              compress_partition
----------------------------------------------------------------------------------------------------------------------------------
 mars_disk_20210401000000000_20210402000000000
(1 row)

Как указано выше, SQL-запрос конвертирует соответствующую секцию за 1 апреля. После преобразования вызовите функцию list_partition, чтобы просмотреть имя и тип хранения преобразованной секции:

ymatrix=# SELECT * from mars.list_partition('disk');
                    relname                    | storage
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 heap_disk_20210402000000000_20210403000000000 | heap
 heap_disk_20210403000000000_20210404000000000 | heap
 heap_disk_20210404000000000_20210405000000000 | heap
 heap_disk_20210405000000000_20210406000000000 | heap
 heap_disk_20210406000000000_20210407000000000 | heap
 heap_disk_20210407000000000_20210408000000000 | heap
 heap_disk_20210408000000000_20210409000000000 | heap
 heap_disk_20210409000000000_20210410000000000 | heap
 heap_disk_20210410000000000_20210411000000000 | heap
 heap_disk_20210411000000000_20210412000000000 | heap
 heap_disk_20210412000000000_20210413000000000 | heap
 heap_disk_20210413000000000_20210414000000000 | heap
 heap_disk_20210414000000000_20210415000000000 | heap
 heap_disk_20210415000000000_20210416000000000 | heap
 heap_disk_20210416000000000_20210417000000000 | heap
 heap_disk_20210417000000000_20210418000000000 | heap
 heap_disk_20210418000000000_20210419000000000 | heap
 heap_disk_20210419000000000_20210420000000000 | heap
 heap_disk_20210420000000000_20210421000000000 | heap
 heap_disk_20210421000000000_20210422000000000 | heap
 heap_disk_20210422000000000_20210423000000000 | heap
 heap_disk_20210423000000000_20210424000000000 | heap
 heap_disk_20210424000000000_20210425000000000 | heap
 heap_disk_20210425000000000_20210426000000000 | heap
 heap_disk_20210426000000000_20210427000000000 | heap
 heap_disk_20210427000000000_20210428000000000 | heap
 heap_disk_20210428000000000_20210429000000000 | heap
 heap_disk_20210429000000000_20210430000000000 | heap
 heap_disk_20210430000000000_20210501000000000 | heap
 mars_disk_20210401000000000_20210402000000000 | mars
(30 rows)

Как видно, префикс имени преобразованной секции изменился с heap на mars, а тип хранения также был изменён соответственно. Старые секции удаляются автоматически.


Функция compress_partition также имеет необязательный параметр временного интервала, позволяющий объединить секцию с предыдущей секцией Mars. Как показано ниже, система автоматически рассчитывает на основе временного интервала и даты текущей секции — следует ли объединить её с предыдущей секцией или создать новую:

SELECT mars.compress_partition('heap_disk_20210401000000000_20210402000000000', '10 days');