IVF On-Disk в Apache Doris
ivf_on_disk — это тип индекса, который Apache Doris предоставляет для крупномасштабного векторного поиска (ANN). Он хранит основную часть инвертированных списков IVF на диске и по мере необходимости загружает востребованные данные через выделенный кэш, значительно сокращая объем постоянно занятой оперативной памяти и сохраняя возможности поиска IVF.
Быстрая навигация
- Чтобы узнать, зачем нужен
ivf_on_disk, прочитайте раздел Предпосылки и цели. - Чтобы сразу начать использовать его при создании таблицы, прочитайте разделы DDL индекса и Параметры запросов.
- Чтобы управлять потреблением памяти, прочитайте разделы Настройка кэша BE и Рекомендации по настройке.
- Чтобы оценить поведение на практике, прочитайте раздел Справочные данные о производительности.
- Для сравнения с 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_limit | 70% | Верхний предел размера кэша. Процент рассчитывается от объема памяти, доступного процессу BE (с учетом ограничения mem_limit), а не от физической памяти всей машины. |
ann_index_ivf_list_cache_stale_sweep_time_sec | 3600 | Интервал очистки устаревших записей в кэше, в секундах. |
Наблюдаемость
Для выявления узких мест производительности ivf_on_disk предусмотрены специальные счетчики Profile и метрики BE. С их помощью можно определить, подходит ли текущий размер кэша и с чем в основном связана задержка: со страничными промахами при обращении к диску или с вычислениями в ходе самого поиска.
Основные поля Profile:
AnnIvfOnDiskLoadCostsAnnIvfOnDiskCacheHitCntAnnIvfOnDiskCacheMissCnt
Основные метрики BE:
ann_ivf_on_disk_fetch_page_costs_msann_ivf_on_disk_fetch_page_cntann_ivf_on_disk_search_costs_msann_ivf_on_disk_search_cntann_ivf_on_disk_cache_hit_cntann_ivf_on_disk_cache_miss_cnt
Особенности использования
- На
ivf_on_diskраспространяются основные ограничения существующих индексов ANN, в том числе требования к типам векторных столбцов и корректности параметров индекса. - Качество обучения и эффективность поиска по-прежнему зависят от объема данных и сочетания параметров (
nlist,ivf_nprobe). ivf_on_diskподдерживает распространенные способы загрузки данных, такие как Stream Load. Перед внедрением в производственную среду рекомендуется проверить его на данных ваших приложений.
Справочные данные о производительности
В следующей таблице приведены результаты эталонного тестирования, которые показывают практический компромисс между охватом данных кэшем, потреблением памяти и задержкой.
| Сценарий | Потребление памяти (ГБ) | Доля попаданий в AnnIndexIVFListCache | Макс. QPS | Recall@100 | Средняя задержка (с) | Задержка P99 (с) | Задержка P95 (с) |
|---|---|---|---|---|---|---|---|
| Полный перебор (без индекса) | - | - | 0.2922 | 0.0000 | 292.5394 | 307.9490 | 307.9442 |
| IVF в памяти | 32.0 | 100% | 71.8535 | 0.9598 | 0.4167 | 0.5623 | 0.5151 |
| Кэш OnDisk 100% | 32.0 | 100% | 72.3649 | 0.9599 | 0.8274 | 1.1236 | 1.0395 |
| Кэш OnDisk 79% | 22.0 | 70% | 45.0266 | 0.9599 | 1.9900 | 4.4059 | 3.3568 |
| Кэш OnDisk 60% | 16.7 | 55% | 38.3141 | 0.9599 | 2.3281 | 4.0063 | 3.5542 |
Как интерпретировать данные:
- При примерно одинаковой полноте поиска (около 0.96) уменьшение кэша значительно снижает потребление памяти, но увеличивает задержки в хвосте распределения.
- Когда охват данных кэшем приближается к 100%,
ivf_on_diskможет обеспечивать полноту поиска, близкую к IVF в памяти, но с некоторым увеличением задержки. - В производственной среде рекомендуется постоянно отслеживать метрику доли попаданий и на ее основе корректировать
ann_index_ivf_list_cache_limit.
Рекомендации по настройке
Рекомендуется настраивать параметры итеративно:
- Начните тестирование с базовых значений параметров
nlist/ivf_nprobe, используемых дляivf. - Задайте
ann_index_ivf_list_cache_limitс учетом доступного объема памяти, затем отслеживайте долю попаданий и изменения задержки. - Если полнота поиска стабильна, но задержка сильно колеблется, в первую очередь увеличьте долю памяти, выделенную под кэш, и повторно проверьте долю попаданий.
- После изменения доли памяти под кэш снова скорректируйте
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, когда требования к задержке особенно строги и памяти достаточно.