Хватит платить за холодные данные: Сокращение расходов на 80 % благодаря горячей и холодной загрузке данных по требованию в многоуровневых хранилищах Milvus
Многие ли из вас до сих пор оплачивают счета за инфраструктуру для данных, к которым ваша система едва прикасается? Скажите честно - большинство команд.
Если вы используете векторный поиск в производстве, вы, вероятно, видели это воочию. Вы выделяете большие объемы памяти и SSD-накопителей, чтобы все оставалось "готовым к работе с запросами", хотя на самом деле активна лишь малая часть вашего набора данных. И вы не одиноки. Мы видели много подобных случаев:
Многопользовательские SaaS-платформы: Сотни подключенных арендаторов, но только 10-15 % активны в любой день. Остальные сидят без дела, но продолжают занимать ресурсы.
Системы рекомендаций для электронной коммерции: Миллион SKU, но 8 % лучших продуктов генерируют большую часть рекомендаций и поискового трафика.
ИИ-поиск: Обширные архивы вложений, хотя 90 % запросов пользователей касаются товаров за последнюю неделю.
Такая же история наблюдается во всех отраслях: менее 10 % ваших данных запрашиваются часто, но на них приходится 80 % хранилища и памяти. Все знают о существовании такого дисбаланса, но до недавнего времени не существовало четкого архитектурного способа его устранения.
Все изменилось с выходом Milvus 2.6.
До этого релиза Milvus (как и большинство векторных баз данных) зависел от модели полной загрузки: если данные должны быть доступны для поиска, они должны быть загружены на локальные узлы. При этом не имело значения, загружаются ли данные тысячу раз в минуту или раз в квартал - все они должны были оставаться горячими. Такой выбор конструкции обеспечивал предсказуемую производительность, но он также означал чрезмерное увеличение размеров кластеров и оплату ресурсов, которых холодные данные просто не заслуживали.
Многоуровневое хранение - вот наш ответ.
В Milvus 2.6 реализована новая многоуровневая архитектура хранения с загрузкой по требованию, позволяющая системе автоматически различать горячие и холодные данные:
Горячие сегменты остаются в кэше рядом с вычислительной машиной.
Холодные сегменты дешево хранятся в удаленном объектном хранилище.
Данные поступают на локальные узлы только тогда, когда они действительно нужны запросу.
Таким образом, структура затрат меняется с "сколько данных у вас есть" на "сколько данных вы реально используете". И в ранних производственных развертываниях этот простой сдвиг обеспечивает снижение затрат на хранение и память до 80 %.
В этой статье мы расскажем о том, как работает многоуровневое хранилище, поделимся реальными результатами производительности и покажем, где это изменение дает наибольший эффект.
Почему полная загрузка разрушается при масштабировании
Прежде чем перейти к рассмотрению решения, стоит подробнее разобраться, почему режим полной загрузки, использовавшийся в Milvus 2.5 и более ранних версиях, стал ограничивающим фактором при масштабировании рабочих нагрузок.
В Milvus 2.5 и более ранних версиях, когда пользователь отправлял запрос Collection.load(), каждый узел QueryNode локально кэшировал всю коллекцию, включая метаданные, данные полей и индексы. Эти компоненты загружаются из хранилища объектов и хранятся либо полностью в памяти, либо отображаются на локальном диске (mmap). Только после того, как все эти данные становятся доступны локально, коллекция помечается как загруженная и готовая к обслуживанию запросов.
Другими словами, коллекция не может быть запрошена до тех пор, пока на узле не появится полный набор данных - горячий или холодный.
Примечание: Для типов индексов, содержащих необработанные векторные данные, Milvus загружает только файлы индекса, а не векторное поле отдельно. Но даже в этом случае индекс должен быть полностью загружен для обслуживания запросов, независимо от того, к какому объему данных на самом деле осуществляется доступ.
Чтобы понять, почему это становится проблематичным, рассмотрим конкретный пример:
Предположим, у вас есть векторный набор данных среднего размера, содержащий:
100 миллионов векторов
768 измерений (вкрапления BERT)
точностьfloat32 (4 байта на измерение)
Индекс HNSW
В этом случае один только индекс HNSW, включая встроенные необработанные векторы, занимает около 430 ГБ памяти. После добавления общих скалярных полей, таких как идентификаторы пользователей, временные метки или метки категорий, общее использование локальных ресурсов легко превышает 500 ГБ.
Это означает, что даже если 80 % данных запрашиваются редко или вообще не запрашиваются, система все равно должна выделять и хранить более 500 ГБ локальной памяти или диска, чтобы поддерживать коллекцию в рабочем состоянии.
Для некоторых рабочих нагрузок такое поведение вполне приемлемо:
Если почти ко всем данным обращаются часто, то полная загрузка всех данных обеспечивает минимальную задержку запросов при максимальной стоимости.
Если данные можно разделить на "горячие" и "теплые" подмножества, то перенос "теплых" данных на диск может частично снизить нагрузку на память.
Однако в рабочих нагрузках, где 80 % или более данных находятся в длинном хвосте, недостатки полной загрузки быстро проявляются как в производительности, так и в стоимости.
Узкие места в производительности
На практике полная загрузка влияет не только на производительность запросов и часто замедляет рутинные рабочие процессы:
Более длительное скользящее обновление: В больших кластерах скользящие обновления могут занимать часы или даже целый день, поскольку каждый узел должен перезагрузить весь набор данных, прежде чем он снова станет доступным.
Более медленное восстановление после сбоев: Когда узел QueryNode перезапускается, он не может обслуживать трафик, пока все данные не будут перезагружены, что значительно увеличивает время восстановления и усиливает последствия сбоев узлов.
Замедление итераций и экспериментов: Полная загрузка замедляет рабочие процессы разработки, заставляя команды ИИ часами ждать загрузки данных при тестировании новых наборов данных или конфигураций индексов.
Неэффективные затраты
Полная загрузка также приводит к росту затрат на инфраструктуру. Например, на оптимизированных по памяти экземплярах основных облаков хранение 1 ТБ данных локально обходится примерно в
Теперь рассмотрим более реалистичную схему доступа, когда 80 % этих данных являются холодными и могут храниться в объектном хранилище (по цене примерно 0,023 долл. / ГБ / месяц):
200 ГБ горячих данных × 5,68 долл.
800 ГБ холодных данных × 0,023 долл.
Годовая стоимость: (200×5,68+800×0,023)×12≈$14 000
Это на 80 % снижает общую стоимость хранения данных, не жертвуя производительностью там, где это действительно важно.
Что такое многоуровневое хранение и как оно работает?
Чтобы устранить этот компромисс, в Milvus 2.6 появилось многоуровневое хранилище, которое балансирует между производительностью и стоимостью, рассматривая локальное хранилище как кэш, а не как контейнер для всего набора данных.
В этой модели узлы запросов при запуске загружают только легкие метаданные. Данные полей и индексы извлекаются по запросу из удаленного хранилища объектов, когда они требуются запросу, и кэшируются локально, если к ним часто обращаются. Неактивные данные могут быть удалены, чтобы освободить место.
В результате "горячие" данные остаются вблизи вычислительного уровня для выполнения запросов с низкой задержкой, а "холодные" данные остаются в объектном хранилище до тех пор, пока не понадобятся. Это сокращает время загрузки, повышает эффективность использования ресурсов и позволяет узлам QueryNodes запрашивать наборы данных, значительно превышающие объем их локальной памяти или диска.
На практике многоуровневое хранилище работает следующим образом:
Храните "горячие" данные локально: Примерно 20 % часто используемых данных остаются на локальных узлах, обеспечивая низкую задержку для 80 % запросов, которые имеют наибольшее значение.
Загружайте холодные данные по требованию: Оставшиеся 80 % редко используемых данных извлекаются только при необходимости, освобождая большую часть локальной памяти и дисковых ресурсов.
Динамическая адаптация с помощью вытеснения на основе LRU: Milvus использует стратегию вытеснения LRU (Least Recently Used), чтобы постоянно корректировать, какие данные считаются горячими или холодными. Неактивные данные автоматически удаляются, чтобы освободить место для новых.
Благодаря такому дизайну Milvus больше не ограничен фиксированной емкостью локальной памяти и диска. Вместо этого локальные ресурсы функционируют как динамически управляемый кэш, где место постоянно освобождается от неактивных данных и перераспределяется в пользу активных рабочих нагрузок.
Такое поведение обеспечивается тремя основными техническими механизмами:
1. Ленивая загрузка
При инициализации Milvus загружает только минимальные метаданные на уровне сегментов, что позволяет коллекциям становиться доступными для запросов практически сразу после запуска. Полевые данные и индексные файлы остаются в удаленном хранилище и извлекаются по требованию во время выполнения запроса, что снижает потребление локальной памяти и диска.
Как работала загрузка коллекций в Milvus 2.5
Как работает ленивая загрузка в Milvus 2.6 и более поздних версиях
Метаданные, загружаемые при инициализации, делятся на четыре основные категории:
Статистика сегмента (основная информация, такая как количество строк, размер сегмента и метаданные схемы)
Временные метки (Используются для поддержки запросов с перемещением во времени)
Вставка и удаление записей (Необходимы для поддержания согласованности данных во время выполнения запросов)
Фильтры Блума (Используются для быстрой предварительной фильтрации, чтобы быстро исключить нерелевантные сегменты).
2. Частичная загрузка
В то время как ленивая загрузка контролирует , когда загружаются данные, частичная загрузка контролирует , сколько данных загружается. Как только начинаются запросы или поиск, узел QueryNode выполняет частичную загрузку, извлекая из хранилища объектов только необходимые фрагменты данных или файлы индексов.
Векторные индексы: Загрузка с учетом интересов арендаторов
Одной из наиболее значимых возможностей, представленных в Milvus 2.6+, является загрузка векторных индексов с учетом арендаторов, разработанная специально для многопользовательских рабочих нагрузок.
Когда запрос обращается к данным одного арендатора, Milvus загружает только ту часть векторного индекса, которая относится к этому арендатору, пропуская данные индекса для всех остальных арендаторов. Таким образом, локальные ресурсы сосредотачиваются на активных арендаторах.
Такая конструкция обеспечивает несколько преимуществ:
Векторные индексы для неактивных арендаторов не занимают локальную память или диск.
Индексные данные для активных арендаторов остаются в кэше для доступа с низкой задержкой
Политика вытеснения LRU на уровне арендаторов обеспечивает справедливое использование кэша для всех арендаторов.
Скалярные поля: Частичная загрузка на уровне столбцов
Частичная загрузка также применяется к скалярным полям, позволяя Milvus загружать только те столбцы, на которые явно ссылается запрос.
Рассмотрим коллекцию с 50 полями схемы, такими как id, vector, title, description, category, price, stock, и tags, а вам нужно вернуть только три поля -id, title, и price.
В Milvus 2.5 все 50 скалярных полей загружаются независимо от требований запроса.
В Milvus 2.6+ загружаются только три запрошенных поля. Остальные 47 полей остаются незагруженными и лениво подбираются только в том случае, если к ним нужно обратиться позже.
Экономия ресурсов может быть значительной. Если каждое скалярное поле занимает 20 ГБ:
Загрузка всех полей требует 1 000 ГБ (50 × 20 ГБ).
Загрузка только трех необходимых полей занимает 60 ГБ.
Это на 94 % сокращает загрузку скалярных данных, не влияя на корректность запросов и результаты.
Примечание: Частичная загрузка скалярных полей и векторных индексов с учетом интересов арендаторов будет официально представлена в одном из ближайших выпусков. Когда она станет доступна, это позволит еще больше сократить задержки при загрузке и повысить производительность холодных запросов в крупных многопользовательских развертываниях.
3. Выгрузка кэша на основе LRU
Ленивая загрузка и частичная загрузка значительно сокращают объем данных, помещаемых в локальную память и на диск. Однако в системах с длительной работой кэш все равно будет расти по мере обращения к новым данным. Когда локальная емкость достигает предела, вступает в силу вытеснение кэша на основе LRU.
Вытеснение на основе LRU (Least Recently Used) подчиняется простому правилу: данные, к которым недавно не было доступа, вытесняются первыми. Это позволяет освободить локальное пространство для новых данных, сохраняя в кэше часто используемые данные.
Оценка производительности: Многоуровневое хранилище по сравнению с полной загрузкой
Чтобы оценить реальное влияние многоуровневого хранения, мы создали тестовую среду, которая в точности повторяет производственные рабочие нагрузки. Мы сравнили Milvus с многоуровневым хранилищем и без него по пяти параметрам: время загрузки, использование ресурсов, производительность запросов, эффективная емкость и экономическая эффективность.
Экспериментальная установка
Набор данных
100 миллионов векторов с 768 измерениями (вкрапления BERT).
Размер векторного индекса: около 430 ГБ
10 скалярных полей, включая идентификатор, временную метку и категорию.
Аппаратная конфигурация
1 узел QueryNode с 4 vCPU, 32 ГБ памяти и 1 ТБ NVMe SSD
Сеть 10 Гбит/с
Кластер объектного хранения MinIO в качестве бэкенда удаленного хранилища
Модель доступа
Запросы следуют реалистичному распределению горячего и холодного доступа:
80 % запросов направлены на данные за последние 30 дней (≈20 % от общего объема данных)
15% - данные за 30-90 дней (≈30% от общего объема данных)
5% - данные старше 90 дней (≈50% всех данных).
Ключевые результаты
1. Ускорение загрузки на 33×
| Этап | Milvus 2.5 | Milvus 2.6+ (многоуровневое хранилище) | Ускорение |
|---|---|---|---|
| Загрузка данных | 22 минуты | 28 секунд | 47× |
| Загрузка индекса | 3 минуты | 17 секунд | 10.5× |
| Всего | 25 минут | 45 секунд | 33× |
В Milvus 2.5 загрузка коллекции занимала 25 минут. С многоуровневым хранилищем в Milvus 2.6+ та же рабочая нагрузка завершается всего за 45 секунд, что представляет собой значительное улучшение эффективности загрузки.
2. Сокращение использования локальных ресурсов на 80 %
| Этап | Milvus 2.5 | Milvus 2.6+ (многоуровневое хранилище) | Сокращение |
|---|---|---|---|
| После нагрузки | 430 ГБ | 12 ГБ | -97% |
| Через 1 час | 430 ГБ | 68 ГБ | -84% |
| Через 24 часа | 430 ГБ | 85 ГБ | -80% |
| Стабильное состояние | 430 ГБ | 85-95 ГБ | ~80% |
В Milvus 2.5 использование локальных ресурсов остается постоянным на уровне 430 ГБ, независимо от нагрузки и времени выполнения. В отличие от этого, Milvus 2.6+ сразу после загрузки начинает использовать всего 12 ГБ.
По мере выполнения запросов часто используемые данные кэшируются локально, и использование ресурсов постепенно увеличивается. Примерно через 24 часа система стабилизируется на уровне 85-95 ГБ, что отражает рабочий набор горячих данных. В долгосрочной перспективе это приводит к сокращению использования локальной памяти и диска на ~80 % без ущерба для доступности запросов.
3. Почти нулевое влияние на производительность горячих данных
| Тип запроса | Задержка Milvus 2.5 P99 | Milvus 2.6+ P99 latency | Изменение |
|---|---|---|---|
| Запросы к горячим данным | 15 мс | 16 мс | +6.7% |
| Запросы с теплыми данными | 15 мс | 28 мс | +86% |
| Запросы к холодным данным (первый доступ) | 15 мс | 120 мс | +700% |
| Холодные запросы к данным (кэшированные) | 15 мс | 18 мс | +20% |
Для горячих данных, на которые приходится около 80 % всех запросов, задержка P99 увеличивается всего на 6,7 %, что практически не оказывает заметного влияния на производительность.
Запросы с холодными данными демонстрируют более высокую задержку при первом доступе из-за загрузки по требованию из объектного хранилища. Однако после кэширования их задержка увеличивается всего на 20 %. Учитывая низкую частоту доступа к холодным данным, этот компромисс в целом приемлем для большинства реальных рабочих нагрузок.
4. Увеличение эффективной емкости в 4,3 раза
При том же аппаратном бюджете - восемь серверов с 64 ГБ памяти каждый (всего 512 ГБ) - Milvus 2.5 может загрузить не более 512 ГБ данных, что эквивалентно примерно 136 миллионам векторов.
При использовании многоуровневого хранилища в Milvus 2.6+ то же самое оборудование может поддерживать 2,2 ТБ данных, или примерно 590 миллионов векторов. Это представляет собой увеличение эффективной емкости в 4,3 раза, что позволяет обслуживать значительно большие наборы данных без увеличения объема локальной памяти.
5. Снижение затрат на 80,1 %
На примере векторного набора данных объемом 2 ТБ в среде AWS и при условии, что 20 % данных являются "горячими" (400 ГБ), сравнение затрат выглядит следующим образом:
| Пункт | Milvus 2.5 | Milvus 2.6+ (многоуровневое хранилище) | Экономия |
|---|---|---|---|
| Ежемесячные расходы | $11,802 | $2,343 | $9,459 |
| Годовая стоимость | $141,624 | $28,116 | $113,508 |
| Уровень экономии | - | - | 80.1% |
Итоги бенчмарка
Во всех тестах многоуровневое хранилище обеспечивает стабильные и измеримые улучшения:
Ускорение загрузки на 33×: Время загрузки коллекции сократилось с 25 минут до 45 секунд.
Снижение использования локальных ресурсов на 80 %: В стационарном режиме работы использование памяти и локального диска снижается примерно на 80 %.
Почти нулевое влияние на производительность горячих данных: Задержка P99 для горячих данных увеличивается менее чем на 10 %, что позволяет сохранить производительность запросов с низкой задержкой.
Контролируемая задержка для холодных данных: При первом обращении к холодным данным возникает более высокая задержка, но это вполне приемлемо, учитывая низкую частоту обращения к ним.
4,3× более высокая эффективная емкость: Одно и то же оборудование может обслуживать в 4-5 раз больше данных без дополнительной памяти.
Снижение затрат более чем на 80 %: Ежегодные расходы на инфраструктуру сокращаются более чем на 80 %.
Когда использовать многоуровневое хранение данных в Milvus
Основываясь на результатах бенчмарков и реальных производственных случаях, мы разделили случаи использования многоуровневого хранилища на три категории, чтобы помочь вам решить, подходит ли оно для вашей рабочей нагрузки.
Наиболее подходящие случаи использования
1. Многопользовательские платформы векторного поиска
Характеристики: Большое количество арендаторов с высокой неравномерностью активности; векторный поиск является основной рабочей нагрузкой.
Модель доступа: Менее 20 % арендаторов генерируют более 80 % векторных запросов.
Ожидаемые преимущества: Снижение затрат на 70-80 %; увеличение пропускной способности на 3-5 ×.
2. Рекомендательные системы электронной коммерции (рабочие нагрузки векторного поиска)
Характеристики: Сильный перекос популярности между топовыми товарами и длинным хвостом.
Характер доступа: На 10 % лучших товаров приходится ~80 % трафика векторного поиска.
Ожидаемые преимущества: Отсутствие необходимости в дополнительных мощностях во время пиковых событий; снижение затрат на 60-70 %.
3. Крупномасштабные наборы данных с четким разделением на "горячие" и "холодные" (с преобладанием векторов).
Характеристики: Наборы данных масштаба ТБ или больше, доступ к которым в значительной степени ориентирован на последние данные.
Модель доступа: Классическое распределение 80/20: 20% данных обслуживают 80% запросов.
Ожидаемые преимущества: 75-85 % снижения затрат.
Подходящие примеры использования
1. Рабочие нагрузки, чувствительные к затратам
Характеристики: Жесткие бюджеты с некоторой терпимостью к незначительным компромиссам по производительности.
Модель доступа: Векторные запросы относительно концентрированы.
Ожидаемые преимущества: Снижение затрат на 50-70 %; холодные данные могут иметь задержку ~500 мс при первом доступе, что должно быть оценено с учетом требований SLA.
2. Хранение исторических данных и архивный поиск
Характеристики: Большие объемы исторических векторов с очень низкой частотой запросов.
Модель доступа: Около 90 % запросов направлены на последние данные.
Ожидаемые преимущества: Сохранение полных исторических наборов данных; сохранение предсказуемости и контроля расходов на инфраструктуру.
Неподходящие сценарии использования
1. Равномерно горячие рабочие нагрузки с данными
Характеристики: Ко всем данным обращаются с одинаковой частотой, без четкого разграничения на "горячие" и "холодные".
Почему не подходит: Ограниченная польза от кэша; дополнительная сложность системы без значимого выигрыша.
2. Рабочие нагрузки со сверхнизкими задержками
Характеристики: Системы с чрезвычайно высокой чувствительностью к задержкам, такие как финансовая торговля или торги в реальном времени.
Почему не подходит: Даже небольшие колебания задержки неприемлемы; полная загрузка обеспечивает более предсказуемую производительность
Быстрый старт: Попробуйте многоуровневое хранение данных в Milvus 2.6+
# Download Milvus 2.6.1+
$ wget https://github.com/milvus-io/milvus/releases/latest
# Configure Tiered Storage
$ vi milvus.yaml
queryNode.segcore.tieredStorage:
warmup:
scalarField: disable
scalarIndex: disable
vectorField: disable
vectorIndex: disable
evictionEnabled: true
# Launch Milvus
$ docker-compose up -d
Заключение
Многоуровневое хранение в Milvus 2.6 позволяет устранить распространенное несоответствие между тем, как хранятся векторные данные, и тем, как к ним фактически обращаются. В большинстве производственных систем часто запрашивается лишь небольшая часть данных, однако традиционные модели загрузки рассматривают все данные как одинаково горячие. Благодаря переходу к загрузке по требованию и управлению локальной памятью и диском в качестве кэша, Milvus приводит потребление ресурсов в соответствие с реальным поведением запросов, а не с наихудшими предположениями.
Такой подход позволяет системам масштабироваться до больших наборов данных без пропорционального увеличения локальных ресурсов, при этом производительность горячих запросов остается практически неизменной. Холодные данные остаются доступными, когда они необходимы, с предсказуемой и ограниченной задержкой, что делает компромисс явным и контролируемым. По мере того как векторный поиск все глубже внедряется в чувствительные к затратам, многопользовательские и длительные производственные среды, Tiered Storage обеспечивает практическую основу для эффективной работы в масштабе.
Для получения дополнительной информации о Tiered Storage ознакомьтесь с документацией ниже:
У вас есть вопросы или вы хотите получить подробную информацию о любой функции последней версии Milvus? Присоединяйтесь к нашему каналу Discord или создавайте проблемы на GitHub. Вы также можете заказать 20-минутный индивидуальный сеанс, чтобы получить знания, рекомендации и ответы на свои вопросы в Milvus Office Hours.
Подробнее о возможностях Milvus 2.6
Представляем Milvus 2.6: доступный векторный поиск в миллиардных масштабах
Представляем функцию встраивания: Как Milvus 2.6 оптимизирует векторизацию и семантический поиск
Измельчение JSON в Milvus: 88,9-кратное ускорение фильтрации JSON с гибкостью
Представление AISAQ в Milvus: векторный поиск миллиардного масштаба стал на 3 200× дешевле по памяти
MinHash LSH в Milvus: секретное оружие для борьбы с дубликатами в обучающих данных LLM
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



