Перейти к содержимому
Последнее обновление

IVF On-Disk в Apache Doris

ivf_on_disk — это тип индекса, который Apache Doris предоставляет для крупномасштабного векторного поиска (ANN). Он хранит основную часть инвертированных списков IVF на диске и по мере необходимости загружает востребованные данные через выделенный кэш, значительно сокращая объем постоянно занятой оперативной памяти и сохраняя возможности поиска IVF.

Быстрая навигация​

Предпосылки и цели​

Когда количество векторов достигает десятков миллионов и более, потребление памяти индексом IVF, полностью размещенным в памяти, быстро растет и становится ресурсным ограничением. При разработке ivf_on_disk ставились следующие цели:

  • Сохранить модель параметров и семантику поиска IVF (nlist / nprobe).
  • Перейти от режима «все данные должны находиться в памяти» к режиму «диск + выделенный кэш».
  • Позволить пользователям продолжать применять привычные запросы ANN на SQL и сложившиеся практики эксплуатации.

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

Сравнение с IVF​

Следующая таблица поможет быстро определить, когда стоит выбрать ivf_on_disk вместо ivf.

Критерий сравненияivf (в памяти)ivf_on_disk (диск + кэш)
Хранение инвертированных списковПолностью в памятиПреимущественно на диске, с загрузкой по мере необходимости через кэш
Потребление памятиВысокое, линейно растет с объемом данныхЗначительно ниже; верхний предел можно явно задать лимитом кэша
Задержка запросовМинимальнаяНемного выше, чем у IVF в памяти; зависит от доли попаданий в кэш
Модель параметровnlist / nprobeТакая же
Функции запросовФункции запросов ANNТакие же
Подходящий масштабМалый и среднийДесятки миллионов и более
Затраты на миграцию-Низкие, требуется только изменить index_type

Интерфейс пользователя​

1) DDL индекса​

Создайте индекс ANN, указав index_type="ivf_on_disk":

CREATE TABLE vec_tbl (
id BIGINT NOT NULL,
embedding ARRAY<FLOAT> NOT NULL,
INDEX idx_emb (embedding) USING ANN PROPERTIES (
"index_type" = "ivf_on_disk",
"metric_type" = "l2_distance",
"dim" = "768",
"nlist" = "1024"
)
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 8
PROPERTIES ("replication_num" = "1");

Основные замечания:

  • Для обоих типов, ivf и ivf_on_disk, необходимо явно указывать nlist.
  • Параметр metric_type поддерживает значения l2_distance и inner_product.
  • Функции запросов остаются прежними: l2_distance_approximate / inner_product_approximate.

2) Параметры запросов​

ivf_nprobe остается ключевым параметром семейства IVF на этапе выполнения запроса:

SET ivf_nprobe = 64;

Как правило, увеличение nprobe повышает полноту поиска, но при этом растет и задержка запросов.

3) Настройка кэша BE​

ivf_on_disk использует выделенный кэш для инвертированных списков IVF. Соответствующие параметры конфигурации BE приведены ниже:

Параметр конфигурацииЗначение по умолчаниюОписание
ann_index_ivf_list_cache_limit70%Верхний предел размера кэша. Процент рассчитывается от объема памяти, доступного процессу BE (с учетом ограничения mem_limit), а не от физической памяти всей машины.
ann_index_ivf_list_cache_stale_sweep_time_sec3600Интервал очистки устаревших записей в кэше, в секундах.

Наблюдаемость​

Для выявления узких мест производительности ivf_on_disk предусмотрены специальные счетчики Profile и метрики BE. С их помощью можно определить, подходит ли текущий размер кэша и с чем в основном связана задержка: со страничными промахами при обращении к диску или с вычислениями в ходе самого поиска.

Основные поля Profile:

  • AnnIvfOnDiskLoadCosts
  • AnnIvfOnDiskCacheHitCnt
  • AnnIvfOnDiskCacheMissCnt

Основные метрики BE:

  • ann_ivf_on_disk_fetch_page_costs_ms
  • ann_ivf_on_disk_fetch_page_cnt
  • ann_ivf_on_disk_search_costs_ms
  • ann_ivf_on_disk_search_cnt
  • ann_ivf_on_disk_cache_hit_cnt
  • ann_ivf_on_disk_cache_miss_cnt

Особенности использования​

  • На ivf_on_disk распространяются основные ограничения существующих индексов ANN, в том числе требования к типам векторных столбцов и корректности параметров индекса.
  • Качество обучения и эффективность поиска по-прежнему зависят от объема данных и сочетания параметров (nlist, ivf_nprobe).
  • ivf_on_disk поддерживает распространенные способы загрузки данных, такие как Stream Load. Перед внедрением в производственную среду рекомендуется проверить его на данных ваших приложений.

Справочные данные о производительности​

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

СценарийПотребление памяти (ГБ)Доля попаданий в AnnIndexIVFListCacheМакс. QPSRecall@100Средняя задержка (с)Задержка P99 (с)Задержка P95 (с)
Полный перебор (без индекса)--0.29220.0000292.5394307.9490307.9442
IVF в памяти32.0100%71.85350.95980.41670.56230.5151
Кэш OnDisk 100%32.0100%72.36490.95990.82741.12361.0395
Кэш OnDisk 79%22.070%45.02660.95991.99004.40593.3568
Кэш OnDisk 60%16.755%38.31410.95992.32814.00633.5542

Как интерпретировать данные:

  • При примерно одинаковой полноте поиска (около 0.96) уменьшение кэша значительно снижает потребление памяти, но увеличивает задержки в хвосте распределения.
  • Когда охват данных кэшем приближается к 100%, ivf_on_disk может обеспечивать полноту поиска, близкую к IVF в памяти, но с некоторым увеличением задержки.
  • В производственной среде рекомендуется постоянно отслеживать метрику доли попаданий и на ее основе корректировать ann_index_ivf_list_cache_limit.

Рекомендации по настройке​

Рекомендуется настраивать параметры итеративно:

  1. Начните тестирование с базовых значений параметров nlist / ivf_nprobe, используемых для ivf.
  2. Задайте ann_index_ivf_list_cache_limit с учетом доступного объема памяти, затем отслеживайте долю попаданий и изменения задержки.
  3. Если полнота поиска стабильна, но задержка сильно колеблется, в первую очередь увеличьте долю памяти, выделенную под кэш, и повторно проверьте долю попаданий.
  4. После изменения доли памяти под кэш снова скорректируйте ivf_nprobe с учетом нового размера кэша, чтобы сбалансировать полноту поиска и задержку.

Часто задаваемые вопросы​

Вопрос 1: Есть ли различия в использовании SQL между ivf_on_disk и ivf?

Различий нет. При создании индекса достаточно изменить index_type на ivf_on_disk. Функции запросов (l2_distance_approximate / inner_product_approximate) и параметры (ivf_nprobe) остаются прежними.

Вопрос 2: От какого объема памяти рассчитывается процент для ann_index_ivf_list_cache_limit?

От объема памяти, доступного процессу BE (с учетом ограничения mem_limit), а не от физической памяти всей машины. Планируйте долю памяти под кэш исходя из верхнего предела памяти BE.

Вопрос 3: Какую долю попаданий можно считать приемлемой?

Это зависит от допустимых для приложения задержек в хвосте распределения. Согласно справочным данным, задержка наиболее стабильна при доле попаданий 100%; когда она снижается до 55%-70%, потребление памяти существенно уменьшается, но задержка P99 может достигать нескольких секунд. Постоянно корректируйте настройки на основе метрик наблюдаемости.

Вопрос 4: Когда следует выбирать ivf_on_disk вместо ivf?

Отдавайте предпочтение ivf_on_disk, когда количество векторов велико (десятки миллионов и более), объем доступной памяти ограничен, а ускорение ANN по-прежнему необходимо. Выбирайте ivf, когда требования к задержке особенно строги и памяти достаточно.