🚀 Prueba Zilliz Cloud, el Milvus completamente gestionado, gratis—¡experimenta un rendimiento 10 veces más rápido! Prueba Ahora>>

milvus-logo
LFAI

Preparación

  • Engineering
April 13, 2020
milvus

En este artículo, describiremos principalmente cómo se registran los datos vectoriales en la memoria de Milvus, y cómo se mantienen estos registros.

A continuación se presentan nuestros principales objetivos de diseño:

  1. La eficiencia de la importación de datos debe ser alta.
  2. Los datos pueden ser vistos tan pronto como sea posible después de la importación de datos.
  3. Evitar la fragmentación de los archivos de datos.

Por lo tanto, hemos establecido un búfer de memoria (búfer de inserción) para insertar datos con el fin de reducir el número de cambios de contexto de IO aleatorio en el disco y el sistema operativo para mejorar el rendimiento de la inserción de datos. La arquitectura de almacenamiento en memoria basada en MemTable y MemTableFile nos permite gestionar y serializar los datos de forma más cómoda. El estado de la memoria intermedia se divide en mutable e inmutable, lo que permite persistir los datos en el disco mientras se mantienen disponibles los servicios externos.

Preparación

Cuando el usuario está listo para insertar un vector en Milvus, primero necesita crear una Colección (* Milvus cambia el nombre de Tabla a Colección en la versión 0.7.0). La Colección es la unidad más básica para registrar y buscar vectores en Milvus.

Cada Colección tiene un nombre único y algunas propiedades que pueden establecerse, y los vectores se insertan o buscan basándose en el nombre de la Colección. Al crear una nueva Colección, Milvus registrará la información de esta Colección en los metadatos.

Inserción de datos

Cuando el usuario envía una solicitud para insertar datos, los datos se serializan y deserializan para llegar al servidor Milvus. A continuación, los datos se escriben en la memoria. La escritura en memoria se divide aproximadamente en los siguientes pasos:

2-data-insertion-milvus.png 2-insercion-datos-milvus.png

  1. En MemManager, busque o cree una nueva MemTable correspondiente al nombre de la colección. Cada MemTable corresponde a una memoria intermedia de la colección.
  2. Un MemTable contendrá uno o más MemTableFile. Cada vez que creemos un nuevo MemTableFile, grabaremos esta información en la Meta al mismo tiempo. Dividimos los MemTableFile en dos estados: Mutable e Inmutable. Cuando el tamaño de MemTableFile alcance el umbral, se convertirá en Inmutable. Cada MemTable sólo puede tener un MemTableFile Mutable para escribir en cualquier momento.
  3. Los datos de cada MemTableFile se grabarán finalmente en la memoria en el formato del tipo de índice establecido. MemTableFile es la unidad más básica para la gestión de datos en memoria.
  4. En cualquier momento, el uso de memoria de los datos insertados no superará el valor preestablecido (insert_buffer_size). Esto se debe a que cada vez que llega una petición de inserción de datos, el MemManager puede calcular fácilmente la memoria ocupada por el MemTableFile contenido en cada MemTable, y luego coordinar la petición de inserción de acuerdo con la memoria actual.

Gracias a la arquitectura multinivel de MemManager, MemTable y MemTableFile, la inserción de datos puede gestionarse y mantenerse mejor. Por supuesto, pueden hacer mucho más que eso.

Consulta casi en tiempo real

En Milvus, sólo hay que esperar un segundo como máximo para que los datos insertados pasen de la memoria al disco. Todo este proceso puede resumirse a grandes rasgos en la siguiente imagen:

2-near-real-time-query-milvus.png 2-consulta-en-tiempo-casi-real-milvus.png

En primer lugar, los datos insertados entrarán en un búfer de inserción en memoria. El búfer cambiará periódicamente del estado Mutable inicial al estado Inmutable en preparación para la serialización. Luego, estos búferes Inmutables serán serializados al disco periódicamente por el hilo de serialización en segundo plano. Una vez colocados los datos, la información del pedido se registrará en los metadatos. En este punto, ¡los datos pueden ser buscados!

Ahora describiremos en detalle los pasos de la imagen.

Ya conocemos el proceso de inserción de datos en el buffer mutable. El siguiente paso es pasar del buffer mutable al buffer inmutable:

3-mutable-buffer-immutable-buffer-milvus.png 3-buffer-mutable-buffer-inmutable-milvus.png

La cola inmutable proporcionará al hilo de serialización en segundo plano el estado inmutable y el MemTableFile listo para ser serializado. Cada MemTable gestiona su propia cola inmutable, y cuando el tamaño del único MemTableFile mutable de la MemTable alcanza el umbral, entrará en la cola inmutable. Un hilo en segundo plano responsable de ToImmutable extraerá periódicamente todos los MemTableFiles de la cola inmutable gestionada por MemTable y los enviará a la cola inmutable total. Debe tenerse en cuenta que las dos operaciones de escribir datos en la memoria y cambiar los datos en la memoria a un estado que no puede ser escrito no pueden ocurrir al mismo tiempo, y se requiere un bloqueo común. Sin embargo, la operación de ToImmutable es muy simple y casi no causa ningún retraso, por lo que el impacto en el rendimiento de los datos insertados es mínimo.

El siguiente paso es serializar el MemTableFile en la cola de serialización a disco. Esto se divide principalmente en tres pasos:

4-serialize-memtablefile-milvus.png 4-serialize-memtablefile-milvus.png

En primer lugar, el hilo de serialización en segundo plano extraerá periódicamente MemTableFile de la cola inmutable. A continuación, se serializan en archivos raw de tamaño fijo (Raw TableFiles). Por último, registraremos esta información en los metadatos. Cuando realicemos una búsqueda vectorial, consultaremos el TableFile correspondiente en los metadatos. A partir de aquí, se pueden realizar búsquedas en estos datos.

Además, de acuerdo con el conjunto index_file_size, después de que el hilo de serialización complete un ciclo de serialización, fusionará algunos TableFiles de tamaño fijo en un TableFile, y también registrará esta información en los metadatos. En este momento, el TableFile puede ser indexado. La creación de índices también es asíncrona. Otro subproceso en segundo plano responsable de la creación de índices leerá periódicamente el FicheroTabla en el estado ToIndex de los metadatos para realizar la correspondiente creación de índices.

De hecho, con la ayuda de TableFile y los metadatos, la búsqueda vectorial resulta más intuitiva y cómoda. En general, tenemos que obtener los ArchivosTabla correspondientes a la Colección consultada a partir de los metadatos, buscar en cada ArchivoTabla y, por último, fusionar. En este artículo, no profundizamos en la implementación específica de la búsqueda.

Si desea saber más, ¡le invitamos a leer nuestro código fuente, o a leer nuestros otros artículos técnicos sobre Milvus!

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started

Like the article? Spread the word

Sigue Leyendo