В этой статье мы обсудим новые параметры для загрузки данных, представленные в 3.0.2
Индекс с данными состоит из нескольких компонентов, таких как словарь, документы и списки результатов, атрибуты. Полный индекс не загружается целиком в ОЗУ, так как он может не влезть, вместо этого его компоненты читаются и загружаются различными способами.
Атрибуты
Атрибуты по умолчанию загружаются в ОЗУ, но возможно выбрать, загружать ли их все, загружать только скалярные типы (целые или вещественные) или хранить их на диске.
Атрибуты загружаются как файлы, отображенные в памяти. Преимущество загрузки атрибутов с использованием mmap()
заключается в более высокой производительности по сравнению с классическим поиском и чтением с использованием pread()
. Это также позволяет использовать большие файлы с небольшими объемами ОЗУ.
В 2.x загрузка атрибутов обрабатывалась через ondisk_attrs
. Даже когда мы выбираем загрузку атрибутов в ОЗУ, чтение целого файла с mmap()
не гарантирует, что страницы файла останутся в ОЗУ, так как ядро ОС может их освободить (это не проблема для приложения, так как отображенные в памяти файлы поддерживаются самим файлом на диске). Чтобы быть уверенным, что атрибуты остаются в ОЗУ и ОС не перемещает их на диск, необходимо использовать mlock
.
В 3.0.2 мы решили внести изменения и вместо настройки для типов загружаемых атрибутов и одной для млокинга сделали две настройки, по каждой для типов атрибутов, которые определяют, как они загружаются и должны ли они быть заблокированы.
Новые настройки это
access_blob_attrs
- которые управляют атрибутами переменной длины (строка, 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_blob_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
), если, например, у вас недостаточно ОЗУ для всех и ваши запросы выполняют больше операций (фильтрация, группировка, сортировка) с атрибутами переменной длины.
Также возможно делать млокинг только некоторых атрибутов. Например, мы хотим, чтобы числовые атрибуты оставались в ОЗУ, но другие атрибуты мы можем загрузить в ОЗУ, но мы согласны не блокировать их, чтобы оставить немного места в памяти, которое можно освободить.
Полнотекстовый индекс
Часть полнотекстового индекса включает в себя несколько компонентов. Компонент словаря (.spi) всегда загружается в ОЗУ, так как это критически важно для производительности полнотекстового поиска, и его размер не велик. Списки документов (.spd) хранят ссылки на индексируемые слова для документов и полей. Этот компонент обычно велик и до сих пор использовался с помощью pread().
Другим компонентом полнотекстового индекса являются списки результатов (.spp
), которые содержат позиции слов в полях. Списки результатов также могут быть большими (но не такими большими, как списки документов) и были доступны таким же образом, как списки документов. Начиная с 3.0.2, оба компонента могут загружаться с помощью mmap()
вместо pread()
, используя
access_doclists
и access_hitlists
. Эта настройка принимает два значения: file
(который использует pread()
и является значением по умолчанию) и mmap
.
Как установить директивы памяти?
По умолчанию используется файл для компонентов полнотекстового индекса и mmap_preread
для всех атрибутов, что является наиболее сбалансированным профилем между использованием памяти и производительностью поиска.
Чтобы убедиться, что данные атрибутов, загруженные в память, не будут сброшены ОС, можно использовать mlock
. Блокировка должна быть на системах, где достаточно памяти для размещения атрибутов, но также оставить достаточно памяти для списков документов/результатов. Наилучшей производительности можно достичь, когда индексы могут быть полностью загружены/кэшированы в ОЗУ. Списки документов/результатов с использованием метода файла могут быть разогреты, отправляя их файлы в /dev/null.
В тех случаях, когда требуется наилучшая производительность с первого запроса, можно использовать опцию --force-preread
для searchd. Эта опция должна использоваться с осторожностью, так как демон не отвечает на входящие запросы, пока завершено запуск. Для одиночных установок это означает, что поисковые запросы невозможны, что может быть неприемлемо в зависимости от времени, необходимого для завершения запуска по сравнению с ответом в это время с большими затратами.
Если индексы больше доступной памяти или допустимо иметь более длительное время разогрева, следует использовать простой file
/mmap
. Если индексы плохо помещаются в ОЗУ, производительность будет зависеть от производительности хранилища. Выбор между большим объемом памяти и более быстрым хранилищем зависит от стоимости каждого. Быстрое хранилище (например, NVMe) снизит недостаток отсутствия достаточного объема памяти. Наличие достаточного объема памяти, но медленного хранилища означает, что старты или перезагрузки индексов будут медленнее, и производительность пострадает, пока индексы не будут загружены в память.