Обработка данных
В этой статье представлено подробное описание реализации в Milvus вставки данных, построения индекса и запроса данных.
Вставка данных
В Milvus вы можете выбрать, сколько шардов будет использоваться в коллекции - каждый шард сопоставляется с виртуальным каналом(vchannel). Как показано ниже, Milvus присваивает каждому vchannel физический канал(pchannel), а каждый pchannel привязывается к определенному узлу потоковой передачи.
VChannel PChannel и StreamingNode
После проверки данных прокси разделит записанное сообщение на различные пакеты данных в соответствии с заданными правилами маршрутизации шардов.
Каналы 1
Затем записанные данные одного шарда(vchannel) отправляются на соответствующий стриминговый узел pchannel.
поток записи
Потоковый узел назначает оракул временных меток (TSO) каждому пакету данных, чтобы установить общий порядок операций. Он выполняет проверку согласованности полезной нагрузки перед записью в базовый журнал с опережением записи (WAL). После того как данные зафиксированы в WAL, они гарантированно не будут потеряны - даже в случае сбоя потоковый узел может воспроизвести WAL для полного восстановления всех незавершенных операций.
Тем временем потоковый узел также асинхронно разбивает зафиксированные записи WAL на отдельные сегменты. Существует два типа сегментов:
- Растущий сегмент: все данные, которые не были предварительно помещены в объектное хранилище.
- Запечатанный сегмент: все данные были сохранены в объектном хранилище, данные запечатанного сегмента неизменяемы.
Переход растущего сегмента в закрытый сегмент называется промывкой. Потоковый узел запускает промывку, как только он проглотил и записал все доступные записи WAL для этого сегмента - т. е. когда в базовом журнале опережающей записи больше нет ожидающих записей - в этот момент сегмент завершается и становится оптимизированным для чтения.
Построение индекса
Построение индекса выполняется узлом данных. Чтобы избежать частого создания индексов при обновлении данных, коллекция в Milvus делится на сегменты, каждый из которых имеет свой собственный индекс.
Построение индекса
Milvus поддерживает построение индекса для каждого векторного поля, скалярного поля и первичного поля. Как на входе, так и на выходе построения индекса происходит взаимодействие с хранилищем объектов: Узел данных загружает снимки журнала для индексации из сегмента (который находится в объектном хранилище) в память, десериализует соответствующие данные и метаданные для построения индекса, сериализует индекс по завершении построения индекса и записывает его обратно в объектное хранилище.
Построение индекса в основном включает в себя операции с векторами и матрицами и, следовательно, требует больших затрат вычислений и памяти. Векторы не могут быть эффективно проиндексированы традиционными древовидными индексами из-за их высокой размерности, но могут быть проиндексированы методами, которые более развиты в этой области, такими как кластерные или графовые индексы. Независимо от типа, построение индекса предполагает массивные итерационные вычисления для крупномасштабных векторов, такие как Kmeans или graph traverse.
В отличие от индексирования скалярных данных, построение векторного индекса должно в полной мере использовать преимущества ускорения SIMD (single instruction, multiple data). Milvus имеет встроенную поддержку наборов инструкций SIMD, например, SSE, AVX2 и AVX512. Учитывая "заминки" и ресурсоемкость построения векторных индексов, эластичность приобретает для Milvus решающее значение с экономической точки зрения. В будущих релизах Milvus будут продолжены исследования в области гетерогенных вычислений и бессерверных вычислений для снижения соответствующих затрат.
Кроме того, Milvus поддерживает скалярную фильтрацию и запросы по первичному полю. Для повышения эффективности запросов в нем имеются встроенные индексы, например, индексы фильтра Блума, хеш-индексы, древовидные индексы и инвертированные индексы, а также планируется внедрение внешних индексов, например, растровых индексов и грубых индексов.
Запрос данных
Запрос данных - это процесс поиска в заданной коллекции k-го количества векторов, ближайших к целевому вектору, или всех векторов в заданном диапазоне расстояний до вектора. Векторы возвращаются вместе с соответствующими первичными ключами и полями.
Запрос данных
Коллекция в Milvus разбивается на несколько сегментов; потоковый узел загружает растущие сегменты и поддерживает данные в реальном времени, а узлы запросов загружают закрытые сегменты.
Когда поступает запрос на запрос/поиск, прокси транслирует его всем потоковым узлам, отвечающим за соответствующие шарды, для одновременного поиска.
Когда поступает запрос на поиск, прокси одновременно запрашивает потоковые узлы, на которых находятся соответствующие шарды, на выполнение поиска.
Каждый потоковый узел генерирует план запроса, выполняет поиск в своих локальных растущих данных и одновременно обращается к удаленным узлам запросов для получения исторических результатов, а затем объединяет их в единый результат по шардам.
Наконец, прокси собирает все результаты шардов, объединяет их в окончательный результат и возвращает его клиенту.
Передача
Когда растущий сегмент на потоковом узле сливается в закрытый сегмент или когда узел данных завершает уплотнение, координатор инициирует операцию handoff для преобразования растущих данных в исторические. Затем координатор равномерно распределяет запечатанные сегменты между всеми узлами запроса, балансируя использование памяти, нагрузку на ЦП и количество сегментов, и освобождает все избыточные сегменты.
Что дальше
- Узнайте, как использовать векторную базу данных Milvus для запросов в реальном времени.
- Узнайте о вставке данных и их сохранении в Milvus.
- Узнайте, как обрабатываются данные в Milvus.