Начиная с Manticore Search 24.4.0, компактизация RT-таблиц использует более эффективную модель выполнения. Вместо последовательного слияния пар чанков здесь появилось два важных улучшения:

  • слияния дисковых чанков могут выполняться параллельно

  • каждая задача слияния может объединять более двух чанков одновременно

  • parallel_chunk_merges : сколько задач слияния дисковых чанков RT может выполняться одновременно

  • merge_chunks_per_job : сколько дисковых чанков RT может объединять одна задача за один проход

Документация по компактизации тоже обновлена: теперь описывается команда OPTIMIZE как N-стороннее слияние, которым занимается пул фоновых воркеров, а не один последовательный тред слияния.

Почему это важно

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

Это особенно заметно, когда:

  • вы загружаете данные с постоянной скоростью

  • optimize_cutoff установлен достаточно низко, чтобы слияния начинались рано

  • вы ждёте завершения компактизации, прежде чем считать загрузку полностью завершённой

Это имеет наибольшее значение в двух типичных случаях:

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

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

Таблица становится доступной для поиска ещё до завершения компактизации, но «полностью доступна для поиска» и «полностью оптимизирована» — не одно и то же. Повышенное число чанков всё равно имеет значение, если вам важно держать таблицу ближе к целевому состоянию, ограничивать объём фоновых слияний до следующей волны загрузки или сокращать окно, в котором хранилище занято постзагрузочной компактизацией.

Чтобы продемонстрировать разницу, мы загрузили 10 миллионов документов в RT‑таблицу. Каждый документ содержит:

  • id bigint

  • name text с сгенерированным текстом от 10 до 100 слов

  • type int

Таблица была создана с помощью:

CREATE TABLE test(id bigint, name text, type int) optimize_cutoff='16'

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

Для бенчмарка мы использовали Manticore Load Emulator — наш инструмент для генерации нагрузки и бенчмарков. Он удобен для воспроизведения таких сценариев, стресс-тестирования загрузки и сравнения конфигурационных изменений без необходимости каждый раз писать собственные скрипты.

Данные были загружены с помощью:

manticore-load \
  --cache-gen-workers=5 \
  --drop \
  --batch-size=1000 \
  --threads=5 \
  --total=10000000 \
  --init="CREATE TABLE test(id bigint, name text, type int) optimize_cutoff='16'" \
  --load="INSERT INTO test(id,name,type) VALUES(<increment>,'<text/10/100>',<int/1/100>)" \
  --wait

Раньше: одна задача слияния, по два чанка за раз

Если принудительно вернуть старое поведение:

mysql -P9306 -h0 -e "set global parallel_chunk_merges=1; set global merge_chunks_per_job=2"

Запуск выглядел так:

  • слияние началось через 14 секунд, когда было вставлено около 1,8M документов

  • все 10M документов были загружены за 1 минуту 18 секунд

  • к этому моменту данные уже были полностью доступны для поиска

  • компактизация продолжала работать в фоне до 3 минут 23 секунд

На 01:18 таблица всё ещё имела более 50 чанков. Ближе к концу загрузки статус выглядел так:

17:14:50  01:17     98%         133      128.4K   21%     5          53        1         4.22GB      9.9M
17:14:51  01:18     100%        131      310.9K   15%     1          53        1         4.27GB      10.0M
...
17:16:55  03:22     100%        0        49.4K    4%      1          17        1         4.27GB      10.0M
...
Total time:       03:23

Это типичная картина: стабильный конвейер загрузки, за которым тянется длинный хвост фоновых слияний.

Теперь: параллельные слияния и больше чанков за одну джобу

С новыми настройками:

mysql -P9306 -h0 -e "set global parallel_chunk_merges=3; set global merge_chunks_per_job=5"

Тот же сценарий завершился заметно быстрее:

  • слияние снова началось примерно через 14 секунд

  • все 10M документов снова были загружены примерно за 1 минуту 18 секунд

  • полная компактизация завершилась всего за 1 минуту 31 секунду

Конец прогона выглядел так:

17:19:22  01:17     99%         127      127.9K   28%     6          26        1         4.22GB      9.9M
17:19:23  01:18     100%        132      1883.8K  17%     1          23        1         4.25GB      10.0M
...
17:19:36  01:31     100%        0        110.2K   3%      1          17        1         4.25GB      10.0M
...
Total time:       01:31

Что изменилось на практике

Сама фаза загрузки почти не изменилась:

  • старые настройки: 1:18 для загрузки всех данных

  • новые настройки: 1:18 для загрузки всех данных

Основной выигрыш пришёлся на компактизацию после загрузки:

  • старые настройки: около 2:05 дополнительного времени слияния после завершения загрузки

  • новые настройки: около 0:13 дополнительного времени слияния после завершения загрузки

Это примерно:

  • на 55 % меньше общее время, с 3:23 до 1:31

  • примерно на 90 % меньше хвост слияний после вставки последнего документа

Число чанков во время загрузки тоже было заметно ниже. Ближе к концу загрузки:

  • старые настройки: 53 чанка

  • новые настройки: 23 чанка

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

Что насчёт новых дефолтов?

На этом же сервере, с новыми дефолтами и вообще без явного тюнинга, тот же сценарий завершился за:

Total time:       01:57

Это уже заметно лучше старого результата 03:23, при этом остаётся пространство для дополнительной настройки с помощью:

  • parallel_chunk_merges

  • merge_chunks_per_job

Иными словами, новые дефолты уже улучшают поведение «из коробки», а системы с достаточным запасом по I/O могут ещё сильнее ускорить компактизацию, если аккуратно увеличивать оба параметра.

Результаты бенчмарков шире: строчное и колоночное хранение

Пример с 10 млн документов выше хорошо показывает механику процесса, но общая картина ещё интереснее. В более широкой матрице тестов мы измерили суммарное время загрузка + оптимизация как для строчного, так и для колоночного хранения при разных значениях:

  • parallel_chunk_merges

  • merge_chunks_per_job

Главный вывод, который мы сделали, — в том, что в некоторых случаях настройка этих параметров может сократить суммарное время загрузки + оптимизации:

  • до 4.6x для строчного хранения

  • до 6.8x для колоночного хранения

Ниже — картина «лучшее против худшего» из этого набора тестов:

Хранилище

Лучшие настройки

Лучшее время

Самые медленные настройки

Самое медленное время

Улучшение

Строчное

parallel_chunk_merges=4merge_chunks_per_job=5

14:35

parallel_chunk_merges=1merge_chunks_per_job=2

67:15

4.61x

Колоночное

parallel_chunk_merges=4merge_chunks_per_job=5

15:10

parallel_chunk_merges=1merge_chunks_per_job=2

99:14

6.80x

В полных результатах также просматривается полезный паттерн тюнинга:

  • лучшие запуски для обоих режимов хранения группируются вокруг parallel_chunk_merges=4..5

  • лучшие запуски также группируются вокруг merge_chunks_per_job=4..5

  • самые медленные результаты постоянно были при parallel_chunk_merges=1 и merge_chunks_per_job=2

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

Что меняют эти две настройки

В новой документации есть две отдельные настройки:

  • parallel_chunk_merges увеличивает количество задач слияния, которые могут выполняться одновременно

  • merge_chunks_per_job увеличивает количество чанков, которые может обрабатывать каждая задача

Низкие значения merge_chunks_per_job упрощают запуск большего числа задач параллельно, потому что каждая задача забирает меньше чанков из доступного пула. Если в таблице много чанков, ожидающих компактизации, более мелкие задачи оставляют больше независимых чанков для других воркеров, поэтому планировщик может одновременно держать активными несколько слияний. Более высокие значения уменьшают общее число шагов слияния, но каждая задача становится тяжелее и забирает большую долю доступных чанков, из-за чего места для параллельных задач остаётся меньше.

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

Вывод

Если из-за RT-нагрузок вам приходится слишком долго ждать завершения компактизации чанков после массовых вставок, новая модель параллельного слияния заметно меняет ситуацию.

В этом тесте с 10 млн документов и параметром optimize_cutoff=16:

Режим

Доступен для поиска в

Полностью оптимизирован в

Старые настройки: parallel_chunk_merges=1merge_chunks_per_job=2

1:18

3:23

Новые дефолты

1:18

1:57

Настроенные новые параметры: parallel_chunk_merges=3merge_chunks_per_job=5

1:18

1:31

  • время до момента, когда все данные стали доступны для поиска, осталось прежним

  • время до завершения сжатия чанков сократилось с 3:23 до 1:31

  • даже новые дефолты сократили общее время до 1:57

Это именно тот тип улучшения, который важен для рабочих RT-нагрузок. Данные становятся доступны для поиска сразу после загрузки, и этот момент в обоих прогонах оставался примерно одинаковым. Разница проявляется позже: насколько долго сервер продолжает тратить ресурсы на фоновую компактизацию чанков, прежде чем таблица вернётся к своей целевой форме. Если ваш рабочий процесс зависит от того, что таблица снова станет компактной до следующей крупной загрузки, до закрытия окна работ или до переключения системы на поисковую нагрузку, которая должна работать с меньшим количеством чанков и меньшей фоновой нагрузкой от слияний, то это улучшение действительно существенно.