Подготовка
В этой статье мы расскажем о том, как векторные данные записываются в память Milvus и как эти записи поддерживаются.
Ниже приведены наши основные цели проектирования:
- Эффективность импорта данных должна быть высокой.
- Данные должны быть видны как можно быстрее после их импорта.
- Избегать фрагментации файлов данных.
Поэтому мы создали буфер памяти (буфер вставки) для вставки данных, чтобы уменьшить количество контекстных переключений случайных операций ввода-вывода на диске и в операционной системе для повышения производительности вставки данных. Архитектура хранения данных в памяти, основанная на MemTable и MemTableFile, позволяет нам более удобно управлять и сериализовать данные. Состояние буфера делится на Mutable и Immutable, что позволяет сохранять данные на диске, сохраняя доступность внешних сервисов.
Подготовка
Когда пользователь готов вставить вектор в Milvus, ему сначала нужно создать коллекцию (* Milvus переименовал таблицу в коллекцию в версии 0.7.0). Коллекция - это самая основная единица для записи и поиска векторов в Milvus.
Каждая Коллекция имеет уникальное имя и некоторые свойства, которые могут быть установлены, и векторы вставляются или ищутся на основе имени Коллекции. При создании новой Коллекции Milvus записывает информацию об этой Коллекции в метаданные.
Вставка данных
Когда пользователь отправляет запрос на вставку данных, данные сериализуются и десериализуются, чтобы попасть на сервер Milvus. Теперь данные записываются в память. Запись в память условно делится на следующие этапы:
2-data-insertion-milvus.png
- В MemManager найдите или создайте новую MemTable, соответствующую имени коллекции. Каждая MemTable соответствует буферу Коллекции в памяти.
- MemTable будет содержать один или несколько MemTableFile. Всякий раз, когда мы создаем новый MemTableFile, мы одновременно записываем эту информацию в Meta. Мы разделяем MemTableFile на два состояния: Mutable и Immutable. Когда размер MemTableFile достигнет порогового значения, он станет неизменяемым. Каждый MemTable может иметь только один Mutable MemTableFile для записи в любой момент времени.
- Данные каждого MemTableFile будут окончательно записаны в память в формате заданного типа индекса. MemTableFile - это самая базовая единица управления данными в памяти.
- В любой момент времени использование памяти для вставленных данных не будет превышать заданного значения (insert_buffer_size). Это происходит потому, что при каждом запросе на вставку данных MemManager может легко вычислить память, занимаемую MemTableFile, содержащимся в каждом MemTable, а затем скоординировать запрос на вставку в соответствии с текущим объемом памяти.
Благодаря многоуровневой архитектуре MemManager, MemTable и MemTableFile, вставка данных может лучше управляться и поддерживаться. Конечно, они могут делать и многое другое.
Запросы почти в реальном времени
В Milvus вам нужно ждать не более одной секунды, пока вставленные данные переместятся из памяти на диск. Весь этот процесс можно вкратце описать на следующей картинке:
2-near-real-time-query-milvus.png
Сначала вставленные данные попадают в буфер вставки в памяти. Буфер будет периодически переходить из начального состояния Mutable в состояние Immutable в процессе подготовки к сериализации. Затем эти Immutable-буферы будут периодически сериализовываться на диск фоновым потоком сериализации. После размещения данных информация о заказе будет записана в метаданные. На этом этапе в данных можно производить поиск!
Теперь мы подробно опишем шаги, изображенные на рисунке.
Мы уже знаем процесс вставки данных в изменяемый буфер. Следующий шаг - переход от мутабельного буфера к мутабельному:
3-mutable-buffer-immutable-buffer-milvus.png
Immutable queue предоставит фоновому потоку сериализации неизменяемое состояние и MemTableFile, готовый к сериализации. Каждый MemTable управляет своей собственной неизменяемой очередью, и когда размер единственного изменяемого MemTableFile достигнет порогового значения, он попадет в неизменяемую очередь. Фоновый поток, отвечающий за ToImmutable, будет периодически вытаскивать все MemTableFiles из неизменяемой очереди, управляемой MemTable, и отправлять их в общую очередь Immutable. Следует отметить, что две операции - запись данных в память и изменение данных в памяти в состояние, которое не может быть записано, - не могут происходить одновременно, поэтому требуется общая блокировка. Однако операция ToImmutable очень проста и практически не вызывает задержек, поэтому влияние производительности на вставляемые данные минимально.
Следующий шаг - сериализация MemTableFile в очереди сериализации на диск. Эта операция в основном делится на три этапа:
4-serialize-memtablefile-milvus.png
Сначала фоновый поток сериализации будет периодически извлекать MemTableFile из неизменяемой очереди. Затем они сериализуются в сырые файлы фиксированного размера (Raw TableFiles). Наконец, мы запишем эту информацию в метаданные. Когда мы проводим векторный поиск, мы запрашиваем соответствующий TableFile в метаданных. Отсюда можно осуществлять поиск по этим данным!
Кроме того, согласно заданному index_file_size, после того как поток сериализации завершит цикл сериализации, он объединит несколько TableFiles фиксированного размера в TableFile, а также запишет эту информацию в метаданные. В это время TableFile может быть проиндексирован. Построение индекса также является асинхронным. Другой фоновый поток, отвечающий за построение индекса, будет периодически читать TableFile в состоянии ToIndex метаданных, чтобы выполнить соответствующее построение индекса.
Векторный поиск
На самом деле, вы увидите, что с помощью TableFile и метаданных векторный поиск становится более интуитивным и удобным. В общем случае нам нужно получить из метаданных TableFiles, соответствующие запрашиваемой Коллекции, выполнить поиск в каждом TableFile и, наконец, объединить их. В этой статье мы не будем углубляться в конкретную реализацию поиска.
Если вы хотите узнать больше, приглашаем вас ознакомиться с нашим исходным кодом или прочитать другие технические статьи о Milvus!
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word