Документ представляет алгоритмы сжатия, используемые в YMatrix, и способы их применения.
Общее сжатие — это алгоритм сжатия, который напрямую сжимает блоки данных, не имея представления о внутренней структуре данных. Такое сжатие часто основано на особенностях двоичных данных для уменьшения избыточности хранимых данных, при этом сжатые данные не могут быть доступны случайным образом. Сжатие и распаковка должны выполняться целиком, блоками данных.
YMatrix поддерживает три алгоритма сжатия для блоков данных: zlib, lz4 и zstd.
Три алгоритма общего сжатия — lz4, zstd и zlib — должны быть указаны в операторе WITH при создании таблиц. Примеры:
=# WITH (compresstype=zstd, compresslevel=3, compress_threshold=1200)
Примечание!
Дополнительную информацию об использовании оператораWITHсм. в разделе CREATE TABLE.
Параметры:
| Имя параметра | Значение по умолчанию | Минимальное значение | Максимальное значение | Описание |
|---|---|---|---|---|
| compress_threshold | 1200 | 1 | 8000 | Порог сжатия. Определяет, сколько кортежей (tuples) сжимается в одной таблице, и является верхним пределом числа сжимаемых кортежей в одном блоке. |
| compresstype | none | Алгоритм сжатия, поддерживаемые значения: 1. zstd 2. zlib 3. lz4 |
||
| compresslevel | 0 | 1 | Уровень сжатия. Чем меньше значение, тем быстрее сжатие, но хуже результат; чем больше значение, тем медленнее сжатие, но лучше результат. Разные алгоритмы имеют разные допустимые диапазоны значений: zstd: 1–19 zlib: 1–9 lz4: 1–20 |
Примечание!
Еслиcompresslevel > 0иcompresstypeне указаны, по умолчанию используетсяcompresstype= zlib.
Если указанcompresstype, но не указанcompresslevel, по умолчанию используетсяcompresslevel= 1.
Примечание!
Как правило, чем выше уровень сжатия, тем выше коэффициент сжатия и ниже скорость. Однако это не абсолютное правило.
Помимо общих алгоритмов сжатия, рекомендуем попробовать собственный разработанный YMatrix алгоритм сжатия — кодирующую цепочку (mxcustom).
В отличие от общего сжатия, основа кодирующей цепочки — это алгоритмы сжатия, которые учитывают формат и семантику данных внутри блока. В реляционной базе данных данные организованы в виде таблиц, и каждый столбец имеет фиксированный тип данных, что обеспечивает логическую схожесть данных в одном столбце. Кроме того, в некоторых сценариях данные соседних строк в бизнес-таблице также могут быть очень похожи. Поэтому, если данные сжимаются по столбцам и хранятся вместе, это обеспечивает лучший эффект сжатия.
Кодирующая цепочка обладает следующими возможностями:
Кодирующая цепочка демонстрирует явные преимущества при сжатии временных рядов. Данные временных рядов обладают характерными особенностями: регулярные временные интервалы, независимость между столбцами, постепенность изменения во времени и т.д. Общие алгоритмы сжатия, такие как lz4 и zstd, ориентированы на потоки байтов и не учитывают эти особенности, поэтому их результат часто далек от идеального.
Кодирующая цепочка эффективно использует особенности данных временных рядов для глубокого сжатия таблиц. Преимущества глубокого сжатия:
Примечание!
Самый простой способ использовать кодирующую цепочку — включить режим адаптивного кодирования (adaptive coding), который автоматически определяет характеристики данных во время выполнения и выбирает подходящий метод кодирования. Подробности ниже.
Основные способы использования кодирующей цепочки представлены в таблице:
| Номер | Использование |
|---|---|
| 1 | Сжатие на уровне столбца |
| 2 | Сжатие на уровне таблицы (поддерживает изменение алгоритма) |
| 3 | Одновременное указание сжатия на уровне таблицы и столбца |
| 4 | Адаптивное кодирование (AutoEncode) |
Подробное описание ниже. Независимо от выбранного способа, необходимо сначала создать расширение:
=# CREATE EXTENSION matrixts;
Настройка пользовательских параметров сжатия для каждого столбца таблицы t1. encodechain используется для указания комбинаций кодирования (можно указать один или несколько алгоритмов). Если указано несколько алгоритмов, они разделяются запятыми. Пример:
=# CREATE TABLE t1(
f1 int8 ENCODING(encodechain='deltadelta(7), zstd', compresstype='mxcustom'),
f2 int8 ENCODING(encodechain='lz4', compresstype='mxcustom')
)
USING MARS3
ORDER BY (f1);
Следующий SQL-запрос также позволяет задать сжатие на уровне столбца:
=# CREATE TABLE t1_1(
f1 int8,COLUMN f1 ENCODING (encodechain='lz4, zstd', compresstype='mxcustom'),
f2 int8,COLUMN f2 ENCODING(encodechain='lz4', compresstype='mxcustom')
)
USING MARS3
ORDER BY (f1);
DEFAULT COLUMN ENCODING означает, что по умолчанию для всех столбцов задается один и тот же алгоритм сжатия — это эквивалентно сжатию на уровне таблицы.
=# CREATE TABLE t1_2(
f1 int8,
f2 int8,
DEFAULT COLUMN ENCODING (encodechain='auto', compresstype='mxcustom')
)
USING MARS3
ORDER BY (f1);
Предположим, вы хотите применить алгоритм сжатия zstd к таблице t2 на уровне таблицы. Есть два варианта: использовать кодирующую цепочку или не использовать её. Основное различие в том, что использование кодирующей цепочки позволяет после создания таблицы изменить алгоритм сжатия с помощью SQL-запросов.
Пример применения кодирующей цепочки для сжатия таблицы t2_1 с использованием алгоритма zstd:
=# CREATE TABLE t2_1 (
f1 int8,
f2 int8
)
USING MARS3
WITH(
compresstype='mxcustom',
encodechain='zstd'
)
ORDER BY (f1);
Пример комбинированного сжатия таблицы t2_2 с использованием алгоритма zstd, lz4:
=# CREATE TABLE t2_2 (
f1 int8,
f2 int8
)
USING MARS3
WITH(
compresstype='mxcustom',
encodechain='zstd, lz4'
)
ORDER BY (f1);
Изменение алгоритма сжатия на уровне таблицы на адаптивное кодирование:
=# ALTER TABLE t2_1 SET (encodechain='auto');
В Примере 1 для таблицы auto задан алгоритм сжатия lz4, а для столбца t3_1 — алгоритм f1. Поскольку параметры сжатия на уровне столбца имеют приоритет над параметрами на уровне таблицы, столбец f1 будет сжат с использованием указанного алгоритма, а остальные столбцы (f2) таблицы t3_1 будут сжаты адаптивно.
=# CREATE TABLE t3_1 (
f1 int8 ENCODING(compresstype='lz4'),
f2 int8
)
USING MARS3
WITH(
compresstype='mxcustom',
encodechain='auto'
)
ORDER BY (f1);
В Примере 2 для таблицы auto задан алгоритм сжатия lz4, deltazigzag, а для столбца t3_2 — алгоритм f1.
=# CREATE TABLE t3_2 (
f1 int8 ENCODING(compresstype='mxcustom', encodechain='lz4, deltazigzag'),
f2 int8
)
USING MARS3
WITH(
compresstype='mxcustom',
encodechain='auto'
)
ORDER BY (f1);
Кодирующая цепочка YMatrix поддерживает адаптивное кодирование: система во время выполнения анализирует характеристики данных и автоматически выбирает оптимальный набор методов кодирования.
Применение адаптивного кодирования на уровне таблицы для таблицы t4:
=# CREATE TABLE t4 (
f1 int8,
f2 int8
)
USING MARS3
WITH(
compresstype=mxcustom
)
ORDER BY (f1);
Также можно явно указать кодирующую цепочку как auto, выбрав один из двух способов:
=# CREATE TABLE t4 (
f1 int8,
f2 int8
)
USING MARS3
WITH(
compresstype=mxcustom,
encodechain=auto
)
ORDER BY (f1);
Укажите адаптивное кодирование на уровне таблицы lz4 и на уровне столбца для таблицы t4. В этом случае столбец f2 будет сжат адаптивно, так как для него не указан конкретный алгоритм.
=# CREATE TABLE t5 (
f1 int8 ENCODING (
compresstype=mxcustom,
encodechain=auto
),
f2 int8
)
USING MARS3
WITH(
compresstype=mxcustom,
encodechain=lz4
)
ORDER BY (f1);
В режиме адаптивного кодирования на уровне таблицы поддерживается Automode с двумя вариантами: приоритет коэффициента сжатия и приоритет скорости. В примере для таблицы t4 включен режим приоритета коэффициента сжатия. automode=1 означает приоритет коэффициента сжатия, automode=2 — приоритет скорости.
-- automode=1, auto for cost
-- automode=2, auto for speed
=# CREATE TABLE t6 (
f1 int8,
f2 int8
)
USING MARS3
WITH(
compresstype=mxcustom,
automode=1
)
ORDER BY (f1);
Примечание!
Адаптивное кодирование нельзя одновременно указывать вместе с другими алгоритмами сжатия.
| Алгоритм | Поддерживаемые параметры | Описание |
|---|---|---|
| lz4 & zstd | compresslevel | Кодирующая цепочка включает lz4 и zstd в комбинации кодирования, используя системные библиотеки сжатия. lz4 подходит для сценариев, где важна скорость, особенно скорость распаковки. zstd более сбалансирован. При стандартном уровне сжатия скорость распаковки lz4 значительно выше, чем у zstd, а коэффициент сжатия zstd явно выше. Как правило, чем выше уровень сжатия zstd, тем выше коэффициент сжатия и ниже скорость. Однако это не абсолютное правило. |
| deltadelta | Масштабирующий коэффициент (опционально). Масштабирующий коэффициент — это количество смещаемых бит. Например, deltadelta(7) означает, что разница масштабируется на 7 бит, а затем сохраняется. По умолчанию масштабирование не применяется | Принцип Delta — вычисление второй разности между соседними значениями, особенно эффективно для отсортированных временных меток. Результат обработки строго упорядоченной последовательности временных меток без пропусков — последовательность нулей, что обеспечивает отличное сжатие. Если некоторые временные метки отсутствуют, разница может остаться большой. deltadelta поддерживает только целые числа и подходит для случаев, когда вторая разность — небольшое целое число. |
| deltazigzag | Масштабирующий коэффициент (опционально) | Принцип deltazigzag: вычисление разницы, затем преобразование возможных отрицательных чисел в положительные с помощью zigzag, далее сжатие с использованием кодирования переменной длины. Подходит для последовательностей целых чисел с небольшими интервалами, без требований к сортировке. |
| Gorilla | Кодирование Gorilla используется для сжатия чисел с плавающей запятой. Принцип — выполнение операции XOR между текущим и предыдущим значением для сжатия нулевых префиксов и суффиксов. В настоящее время поддерживается только тип double (8 байт). | |
| Gorilla2 | Оптимизированная версия Gorilla. Gorilla2 лучше улавливает распространённые характеристики данных. В большинстве временных сценариев коэффициент сжатия Gorilla2 значительно выше, чем у Gorilla. Кроме того, Gorilla2 по коэффициенту сжатия и времени сжатия сопоставим с zstd, но превосходит его по скорости распаковки. Поддерживает типы float4 и float8. | |
| Floatint | Масштабирующий коэффициент (обязательный) | В некоторых случаях сжатие чисел с плавающей запятой с помощью Gorilla неэффективно. Например, в сценарии IoT, где координаты автомобиля — медленно меняющиеся значения с плавающей запятой, коэффициент сжатия Gorilla почти нулевой. Комбинация floatint и deltadelta может дать более чем в 10 раз лучший результат. Это объясняется особым внутренним представлением чисел с плавающей запятой: изменения соседних значений малы, XOR не даёт много нулей, но целочисленная последовательность после масштабирования сохраняет схожесть и легче сжимается. Важно: масштабирование floatint вносит погрешность, величина которой зависит от масштабирующего коэффициента. Например, при коэффициенте 4 максимальная погрешность составляет 0.0001. |
| simple8b | simple8b подходит для целых чисел с небольшим диапазоном. Принцип — хранение нескольких малых целых чисел в 8 байтах. Например, если данные содержат целые числа < 8, то каждые 3 числа помещаются в один байт, обеспечивая лучшее сжатие. В таких случаях lz4 может давать плохой результат из-за нерегулярности данных. | |
| fds | В сценариях временных рядов часто используются числа с плавающей запятой для хранения целочисленной информации. fds — специальный код, разработанный для этого случая. Он определяет, что данные на самом деле являются целыми числами, преобразует их в двоичные целые и дополнительно сжимает. На наборе данных TSBS cpu-only (всего 13 столбцов, из них 10 числовых — случайные целые числа, хранящиеся как float8), коэффициент сжатия fds в 2 раза выше, чем у zstd (размер после сжатия составляет 30% от размера zstd). |