Tarantool CE/EE Documentation portal logo
Помощь
Обновлена 15 сентября 2026 г. в 08:55

Хранение данных с помощью memcs

Движок memcs использует однопоточный обработчик транзакций (поток TX), аналогично memtx, и хранит данные в арене memtx, но в отличие от memtx не организует данные в кортежи. Вместо этого данные хранятся по колонкам. Каждому полю формата назначается собственная древовидная структура типа BPS (BPS-вектор), в которой хранятся значения только этого поля. Если тип поля помещается в 32 байта, исходные значения поля хранятся непосредственно в листьях дерева без какого-либо кодирования. Строки хранятся в формате, аналогичном «Arrow Variable-size Binary View Layout», также называемом «German Strings».

Главное преимущество такой организации данных – значительное повышение производительности последовательного сканирования колоночных данных по сравнению с memtx благодаря локальности кэша процессора. Поэтому в memcs поддерживается специальный C API для таких колоночных сканирований: см. box_index_arrow_stream() и box_raw_read_view_arrow_stream(). Пиковая производительность достигается при сканировании встроенных типов полей.

Запрос полных кортежей, как в memtx, также поддерживается, но производительность ниже по сравнению с memtx, поскольку кортеж приходится конструировать в арене среды выполнения (runtime arena) из отдельных значений полей, собранных из каждого дерева колонок.

Другие возможности:

  • Точечный поиск;
  • Стабильные итераторы;
  • Вставка / замена / удаление / обновление;
  • Пакетная вставка в формате Arrow;
  • Транзакции, включая транзакции между движками с memtx (при memtx_use_mvcc_engine = false);
  • Поддержка представления для чтения;
  • Вторичные индексы с возможностью указания покрываемых колонок и последовательного сканирования индексированных и покрываемых колонок.

Ключевые возможности

  • Колоночная организация данных – данные хранятся по колонкам, что обеспечивает эффективную агрегацию, фильтрацию и сканирование.
  • Поддержка Apache Arrow – данные можно экспортировать в формате Arrow без преобразования, что обеспечивает взаимодействие без копирования.
  • Кодирование по словарю – снижает использование памяти для строковых колонок с повторяющимися значениями.
  • Сжатие LZ4 – сжимает данные колонок для уменьшения объема используемой памяти.

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

memcs используется как движок хранения для объектов space и создается с помощью функции box.schema.space.create():

box.schema.create_space('analytics_data', {    engine = 'memcs',    field_count = 4,    format = {        {name = 'id', type = 'uint64'},        {name = 'event_type', type = 'string', compression = 'lz4'},        {name = 'timestamp', type = 'datetime'},        {name = 'value', type = 'double', compression = {type = 'lz4', acceleration = 1000}},    }})

Поддерживаемые типы данных

Движок memcs поддерживает широкий диапазон типов данных, включая:

  • Целочисленные типы: int8, uint8, int16, uint16, int32, uint32, int64, uint64;
  • Типы с плавающей точкой: double, float, float32, float64;
  • Строки: string;
  • Decimal: decimal, decimal32, decimal64, decimal128 и decimal256.

Кодирование по словарю

В движке memcs поддерживается кодирование по словарю для строковых колонок. Уникальные строковые значения хранятся в общем словаре, а повторяющиеся значения заменяются небольшими целочисленными идентификаторами. Кодирование по словарю включается с помощью опции index_opts.layout:

local s = box.schema.create_space('test', {    engine = 'memcs', format = format, field_count = field_count,})s:create_index('pk', {layout = 'dict'})

Ограничения:

  • Поддерживаются только неключевые строковые колонки.
  • Максимум UINT16_MAX (65536) уникальных значений на колонку.
  • Идентификаторы в словаре используют тип uint16 (2 байта на значение).

Использование памяти: 2 * space_size + dict_size

Память, используемая словарем, включена в статистику space:bsize().

Гарантии ArrowStream:

  • Словарь возвращается как string-view, индексы как uint16
  • Все пакеты используют общий словарь, пока не вставлены новые уникальные значения
  • Словари возвращаются по ссылке (без копирования), поэтому экспорт ArrowArray выполняется эффективно
  • Словари только увеличиваются – ранее созданные пакеты остаются совместимыми

Макеты колонок

В memcs поддерживается задание макетов колонок на нескольких уровнях. Приоритет следующий (от высшего к низшему):

  1. Внутри index_opts.covers в определении индекса.
  2. Внутри index_opts.layout в определении индекса (по умолчанию для nullable-полей).
  3. Внутри format в определении спейса.
-- 1. Внутри coversbox.space.test:create_index('sk', {    parts = {'c2', 'c3'},    covers = {        {'c4', layout = 'plain'},        {'c5', layout = 'null_rle'},    },})-- 2. Внутри layoutbox.space.test:create_index('sk', {    parts = {'c2', 'c3'},    covers = {'c4', 'c5'},    layout = 'null_rle',})-- 3. Внутри formatbox.space.test:format({    {name = "c2", type = "number"},    {name = "c3", type = "number"},    {name = "c4", type = "number", is_nullable = true, layout = 'null_rle'},    {name = "c5", type = "number", is_nullable = true},})

Поддерживаемые макеты:

  • plain – макет по умолчанию, без кодирования.
  • null_rle – RLE-кодирование для nullable-полей.
  • dict – кодирование по словарю для строковых полей.

RLE-кодирование NULL-значений

По умолчанию значения NULL хранятся явно и занимают такой же объем памяти, как и любое другое допустимое значение колонки (1, 2, 4, 8, 16 или 32 байта в зависимости от точного типа поля). Однако также поддерживается RLE-кодирование NULL-значений с помощью макета null_rle. Например, в колонке с 90% равномерно распределенных значений NULL RLE-кодирование снижает потребление памяти примерно в 5 раз.

Макет null_rle можно задать на трех уровнях:

  • Внутри covers в определении индекса (наивысший приоритет).
  • Внутри layout в определении индекса (по умолчанию для nullable-полей).
  • Внутри format при определении спейса (низший приоритет).

Сжатие LZ4

В memcs поддерживается сжатие на уровне колонок с использованием алгоритма LZ4, который обеспечивает баланс между скоростью и коэффициентом сжатия. Подробности о движках сжатия см. в разделе Сжатие столбцов.