⚠️ Эта страница автоматически переведена, и перевод может быть несовершенным.

New options for loading indexes

В этой статье мы рассказываем о новых опциях загрузки данных, представленных в версии 3.0.2

Индекс с данными состоит из нескольких компонентов, таких как словарь, документы и списки хитов, атрибуты. Весь индекс не загружается полностью в ОЗУ, поскольку может не поместиться, вместо этого его компоненты читаются и загружаются разными способами.

Атрибуты

По умолчанию атрибуты загружаются в ОЗУ, но была возможность выбирать, загружать их все, загружать только скалярные типы (целые или числа с плавающей точкой) или оставлять их на диске.

Атрибуты загружаются как файлы с отображением в память. Преимущество загрузки атрибутов с помощью mmap() — лучшая производительность по сравнению с классическим seek&read с использованием pread(). Это также позволяет работать с большими файлами, используя небольшие объёмы ОЗУ.

В версии 2.x загрузка атрибутов осуществлялась через ondisk_attrs. Даже если мы выбираем загрузку атрибутов в ОЗУ, чтение всего файла с помощью mmap() не гарантирует, что страницы файла останутся в ОЗУ, так как ядро ОС может их освободить (это не проблема для приложения, поскольку mmap‑файлы поддерживаются самим файлом на диске). Чтобы убедиться, что атрибуты остаются в ОЗУ и ОС не выгружает их на диск, необходимо использовать mlock.

В версии 3.0.2 мы решили внести изменение и вместо наличия отдельного параметра для типов загружаемых атрибутов и параметра для mlock использовать два параметра, каждый из которых определяет типы атрибутов, способ их загрузки и необходимость блокировки.

Новые настройки — access_blob_attrs — управляет переменной длиной атрибутов (string, JSON, MVA) — и access_plain_attrs — управляет атрибутами фиксированной длины (uint, bigint, float, timestamp, bool). Возможные значения: mmap, mmap_preread и mlock.

Переход от старых директив к новым довольно прост:

  • ondisk_attrs = 0 означает, что ни один атрибут не оставлен на диске и они предварительно читаются в ОЗУ. Это было значение по умолчанию вместе с mlock=0. Сейчас это эквивалентно access_blob_attrs = mmap_preread и access_plain_attrs= mmap_preread. Этот режим следует использовать, когда все атрибуты могут поместиться в ОЗУ. Чтобы убедиться, что они не выгружаются на диск, можно вместо этого использовать access_blog_attrs = mlock и access_plain_attrs = mlock, что эквивалентно ondisk_attrs=0 и mlock=1.
  • ondisk_attrs=1 означает, что все атрибуты оставлены на диске. С новыми опциями необходимо указать access_blob_attrs=mmap и access_plain_attrs=mmap.
  • ondisk_attrs=pool означает оставлять строки, JSON и MVA‑атрибуты на диске. Чтобы получить тот же эффект сейчас, нужно задать access_blob_attrs=mmap и access_plain_attrs=mmap_preread.

Но теперь также возможно оставлять числовые атрибуты на диске и загружать вместо них переменной длины (делая access_blob_attrs=mmap_preread/access_plain_attrs=mmap), если, например, у вас недостаточно ОЗУ для всех атрибутов, а ваши запросы выполняют больше операций (фильтрация, группировка, сортировка) над переменной длиной.

Также возможно выполнять mlock только для некоторых атрибутов. Например, мы хотим, чтобы числовые атрибуты гарантированно оставались в ОЗУ, а остальные атрибуты можно предварительно читать в ОЗУ, но не блокировать их, чтобы освободить часть памяти.

Полнотекстовый индекс

Полнотекстовая часть индекса сама по себе включает несколько компонентов. Компонент словаря (.spi) всегда загружается в ОЗУ, поскольку он критичен для производительности полнотекстового поиска и его размер небольшой. Списки документов (.spd) содержат ссылки индексированных слов на документы и поля. Этот компонент обычно большой и до этого доступа осуществлялись с помощью pread().

Другим компонентом полнотекстового индекса являются списки хитов (.spp), которые содержат позиции слов в полях. Списки хитов также могут быть большими (но не так большими, как списки документов) и до этого доступ к ним осуществлялся так же, как к спискам документов. Начиная с версии 3.0.2 оба компонента могут загружаться с помощью mmap() вместо pread(), используя access_doclists и access_hitlists. Параметр принимает два значения: file (который использует pread() и является значением по умолчанию) и mmap.

Как задать директивы памяти?

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

Чтобы убедиться, что данные атрибутов, загруженные в память, не будут выгружены ОС, можно использовать mlock. Блокировка должна применяться на системах, где достаточно памяти для размещения атрибутов, но при этом остаётся достаточно памяти для списков документов/хитов. Наилучшая производительность достигается, когда индексы могут быть полностью загружены/кешированы в ОЗУ. Списки документов/хитов, использующие метод file, можно прогреть, отправив их файлы в /dev/null.

В случаях, когда требуется максимальная производительность уже с первого запроса, можно использовать опцию --force-preread демона searchd. Эта опция должна использоваться с осторожностью, поскольку демон не отвечает на входящие запросы, пока не завершится запуск. Для одиночных установок это означает, что поисковые запросы невозможны, что может быть неприемлемо в зависимости от времени, необходимого для завершения запуска, по сравнению с более длительным временем отклика в этот период.

Если индексы больше доступной памяти или приемлемо более длительное время прогрева, следует использовать простой file/mmap. Если индексы не помещаются в ОЗУ, производительность будет зависеть от скорости хранилища. Выбор между большим объёмом памяти и более быстрым хранилищем зависит от их стоимости. Более быстрое хранилище (например, NVMe) уменьшит недостаток недостатка памяти. Наличие достаточного объёма памяти, но медленного хранилища приводит к более медленному запуску или перезагрузке индексов, и производительность будет страдать, пока индексы не загрузятся в память.

Установить Manticore Search

Установить Manticore Search