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

milvus-logo
LFAI
  • Home
  • Blog
  • Inserción y persistencia de datos en una base de datos vectorial

Inserción y persistencia de datos en una base de datos vectorial

  • Engineering
April 06, 2022
Bingyi Sun

Cover image Imagen de portada

Este artículo ha sido escrito por Bingyi Sun y transcrito por Angela Ni.

En el post anterior de la serie Deep Dive, hemos presentado cómo se procesan los datos en Milvus, la base de datos vectorial más avanzada del mundo. En este artículo, continuaremos examinando los componentes que intervienen en la inserción de datos, ilustraremos el modelo de datos en detalle y explicaremos cómo se logra la persistencia de datos en Milvus.

Ir a:

Recapitulación de la arquitectura Milvus

Milvus architecture. Arquitectura de Milvus.

El SDK envía solicitudes de datos al proxy, el portal, a través del equilibrador de carga. A continuación, el proxy interactúa con el servicio coordinador para escribir solicitudes DDL (lenguaje de definición de datos) y DML (lenguaje de manipulación de datos) en el almacenamiento de mensajes.

Los nodos de trabajo, incluidos el nodo de consulta, el nodo de datos y el nodo de índice, consumen las solicitudes del almacenamiento de mensajes. Más concretamente, el nodo de consulta se encarga de la consulta de datos; el nodo de datos es responsable de la inserción y persistencia de datos; y el nodo de índice se ocupa principalmente de la creación de índices y la aceleración de consultas.

La capa inferior es el almacenamiento de objetos, que aprovecha principalmente MinIO, S3 y AzureBlob para almacenar registros, binlogs delta y archivos de índice.

El portal de solicitudes de inserción de datos

Proxy in Milvus. Proxy en Milvus.

Proxy sirve como portal de solicitudes de inserción de datos.

  1. Inicialmente, el proxy acepta solicitudes de inserción de datos de los SDK y asigna esas solicitudes en varios buckets utilizando un algoritmo hash.
  2. A continuación, el proxy solicita al coordinador de datos que asigne segmentos, la unidad más pequeña de Milvus para el almacenamiento de datos.
  3. A continuación, el proxy inserta la información de los segmentos solicitados en el almacén de mensajes para que dicha información no se pierda.

Coordinación de datos y nodo de datos

La función principal del coordinador de datos es gestionar la asignación de canales y segmentos, mientras que la función principal del nodo de datos es consumir y persistir los datos insertados.

Data coord and data node in Milvus. Coordinación de datos y nodo de datos en Milvus.

Función

La función de la coordinación de datos es la siguiente

  • Asignar espacioen segmentos Data coord asigna espacio en segmentos crecientes al proxy para que éste pueda utilizar el espacio libre en segmentos para insertar datos.

  • Registrar la asignación de segmento y eltiempo de expiracióndel espacio asignado en elsegmento El espacio dentro de cada segmento asignado por el data coord no es permanente, por lo tanto, el data coord también necesita mantener un registro del tiempo de expiración de cada asignación de segmento.

  • Descarga automáticade datos del segmento Si el segmento está lleno, el coordinador de datos activa automáticamente la descarga de datos.

  • Asignación de canales a nodos de datosUna colección puede tener varios canales variables. El coordenador de datos determina qué vcanales son consumidos por qué nodos de datos.

El nodo de datos sirve en los siguientes aspectos:

  • ConsumirdatosEl nodo de datos consume datos de los canales asignados por data coord y crea una secuencia para los datos.

  • Persistencia dedatos Almacena en caché los datos insertados en la memoria y los vuelca automáticamente en el disco cuando el volumen de datos alcanza un determinado umbral.

Flujo de trabajo

One vchannel can only be assigned to one data node. Un vchannel sólo puede ser asignado a un nodo de datos.

Como se muestra en la imagen anterior, la colección tiene cuatro vcanales (V1, V2, V3 y V4) y hay dos nodos de datos. Es muy probable que la coordenada de datos asigne un nodo de datos para consumir datos de V1 y V2, y el otro nodo de datos de V3 y V4. No se puede asignar un mismo vchannel a varios nodos de datos y esto es para evitar la repetición del consumo de datos, que de lo contrario provocaría que el mismo lote de datos se insertara en el mismo segmento repetidamente.

Root coord y Time Tick

Root coord gestiona TSO (timestamp Oracle) y publica mensajes de marca de tiempo a nivel global. Cada solicitud de inserción de datos tiene una marca de tiempo asignada por root coord. Time Tick es la piedra angular de Milvus que actúa como un reloj en Milvus y significa en qué punto del tiempo se encuentra el sistema Milvus.

Cuando se escriben datos en Milvus, cada solicitud de inserción de datos lleva una marca de tiempo. Durante el consumo de datos, cada nodo de datos de tiempo consume datos cuyas marcas de tiempo están dentro de un rango determinado.

An example of data insertion and data consumption based on timestamp. Ejemplo de inserción y consumo de datos basado en la marca de tiempo.

La imagen anterior muestra el proceso de inserción de datos. El valor de las marcas de tiempo está representado por los números 1,2,6,5,7,8. Los datos se escriben en el sistema mediante dos proxies: p1 y p2. Durante el consumo de datos, si la hora actual de la marca de tiempo es 5, los nodos de datos sólo pueden leer los datos 1 y 2. Luego, durante la segunda lectura, si el tiempo actual del Time Tick es 9, los datos 6,7,8 pueden ser leídos por el nodo de datos.

Organización de datos: colección, partición, shard (canal), segmento

Data organization in Milvus. Organización de datos en Milvus.

Lea este artículo primero para entender el modelo de datos en Milvus y los conceptos de colección, fragmento, partición y segmento.

En resumen, la unidad de datos más grande en Milvus es una colección que puede compararse a una tabla en una base de datos relacional. Una colección puede tener múltiples fragmentos (cada uno correspondiente a un canal) y múltiples particiones dentro de cada fragmento. Como se muestra en la ilustración anterior, los canales (shards) son las barras verticales, mientras que las particiones son las horizontales. En cada intersección se encuentra el concepto de segmento, la unidad más pequeña para la asignación de datos. En Milvus, los índices se construyen sobre segmentos. Durante una consulta, el sistema Milvus también equilibra las cargas de consulta en diferentes nodos de consulta y este proceso se lleva a cabo basándose en la unidad de segmentos. Los segmentos contienen varios binlogs, y cuando se consumen los datos del segmento, se genera un archivo binlog.

Segmento

Existen tres tipos de segmentos con diferentes estados en Milvus: segmento creciente, segmento sellado y segmento vaciado.

Segmento creciente

Un segmento creciente es un segmento recién creado que puede asignarse al proxy para la inserción de datos. El espacio interno de un segmento puede ser utilizado, asignado o libre.

Three status in a growing segment Hay tres estados en un segmento en crecimiento

  • Utilizado: esta parte del espacio de un segmento en crecimiento ha sido consumida por el nodo de datos.
  • Asignado: esta parte del espacio de un segmento en crecimiento ha sido solicitada por el proxy y asignada por el nodo de datos. El espacio asignado caducará al cabo de cierto tiempo.
  • Libre: esta parte del espacio de un segmento en crecimiento no se ha utilizado. El valor del espacio libre es igual al espacio total del segmento restado por el valor del espacio utilizado y asignado. Por lo tanto, el espacio libre de un segmento aumenta a medida que el espacio asignado caduca.

Segmento sellado

Un segmento sellado es un segmento cerrado que ya no puede ser asignado al proxy para la inserción de datos.

Sealed segment in Milvus Segmento sellado en Milvus

Un segmento en crecimiento se sella en las siguientes circunstancias:

  • Si el espacio utilizado en un segmento en crecimiento alcanza el 75% del espacio total, el segmento se sellará.
  • Flush() es llamada manualmente por un usuario de Milvus para persistir todos los datos en una colección.
  • Los segmentos crecientes que no se sellen después de un largo período de tiempo se sellarán, ya que demasiados segmentos crecientes hacen que los nodos de datos consuman demasiada memoria.

Segmento vaciado

Un segmento vaciado es un segmento que ya se ha escrito en el disco. Flush se refiere a almacenar los datos del segmento en el almacenamiento de objetos para la persistencia de los datos. Un segmento sólo puede ser vaciado cuando expira el espacio asignado en un segmento sellado. Cuando se descarga, el segmento sellado se convierte en un segmento descargado.

Flushed segment in Milvus Segmento vaciado en Milvus

Canal

Un canal se asigna :

  • Cuando el nodo de datos se inicia o se cierra; o
  • Cuando el espacio del segmento asignado es solicitado por el proxy.

Existen varias estrategias de asignación de canales. Milvus soporta 2 de las estrategias:

  1. Hashing consistente

Consistency hashing in Milvus Hashing consistente en Milvus

La estrategia por defecto en Milvus. Esta estrategia aprovecha la técnica hashing para asignar a cada canal una posición en el anillo, y luego busca en el sentido de las agujas del reloj para encontrar el nodo de datos más cercano a un canal. Así, en la ilustración anterior, el canal 1 se asigna al nodo de datos 2, mientras que el canal 2 se asigna al nodo de datos 3.

Sin embargo, uno de los problemas de esta estrategia es que el aumento o la disminución del número de nodos de datos (por ejemplo, el inicio de un nuevo nodo de datos o el cierre repentino de un nodo de datos) puede afectar al proceso de asignación de canales. Para resolver este problema, data coord supervisa el estado de los nodos de datos a través de etcd, de modo que data coord pueda ser notificado inmediatamente si se produce algún cambio en el estado de los nodos de datos. A continuación, el coordinador de datos determina a qué nodo de datos asignar los canales correctamente.

  1. Equilibrio de la carga

La segunda estrategia consiste en asignar canales de la misma colección a diferentes nodos de datos, garantizando que los canales se asignen de forma equitativa. El objetivo de esta estrategia es lograr el equilibrio de carga.

Asignación de datos: cuándo y cómo

The process of data allocation in Milvus El proceso de asignación de datos en Milvus

El proceso de asignación de datos parte del cliente. Primero envía solicitudes de inserción de datos con una marca de tiempo t1 al proxy. A continuación, el proxy envía una solicitud de asignación de segmentos al coordinador de datos.

Al recibir la solicitud de asignación de segmento, el coordinador de datos comprueba el estado del segmento y lo asigna. Si el espacio actual de los segmentos creados es suficiente para las nuevas filas de datos insertadas, el coordinador de datos asigna los segmentos creados. Sin embargo, si el espacio disponible en los segmentos actuales no es suficiente, el coordenador de datos asignará un nuevo segmento. El coordinador de datos puede devolver uno o más segmentos en cada solicitud. Mientras tanto, el coordinador de datos también guarda el segmento asignado en el metiservidor para la persistencia de los datos.

Posteriormente, el coordinador de datos devuelve la información del segmento asignado (incluido el ID del segmento, el número de filas, el tiempo de expiración t2, etc.) al proxy. El proxy envía dicha información del segmento asignado al almacén de mensajes para que dicha información quede debidamente registrada. Tenga en cuenta que el valor de t1 debe ser menor que el de t2. El valor por defecto de t2 es de 2.000 milisegundos y puede cambiarse configurando el parámetro segment.assignmentExpiration en el archivo data_coord.yaml.

Estructura del archivo Binlog y persistencia de datos

Data node flush Descarga del nodo de datos

El nodo de datos se suscribe al almacén de mensajes porque las solicitudes de inserción de datos se guardan en el almacén de mensajes y los nodos de datos pueden así consumir mensajes de inserción. Los nodos de datos colocan primero las solicitudes de inserción en un búfer de inserción y, a medida que las solicitudes se acumulan, se vaciarán en el almacenamiento de objetos tras alcanzar un umbral.

Estructura del archivo Binlog

Binlog file structure. Estructura del archivo binlog.

La estructura del archivo binlog en Milvus es similar a la de MySQL. Binlog se utiliza para dos funciones: recuperación de datos y creación de índices.

Un binlog contiene muchos eventos. Cada evento tiene un encabezado y datos de evento.

Los metadatos, como la hora de creación del binlog, el ID del nodo de escritura, la longitud del evento y NextPosition (desplazamiento del siguiente evento), etc., se escriben en la cabecera del evento.

Los datos del evento pueden dividirse en dos partes: fijos y variables.

File structure of an insert event. Estructura del archivo de un evento de inserción.

La parte fija en los datos de evento de un INSERT_EVENT contiene StartTimestamp, EndTimestamp, y reserved.

La parte variable, de hecho, almacena los datos insertados. Los datos de inserción se secuencian en el formato de parquet y se almacenan en este archivo.

Persistencia de los datos

Si hay varias columnas en el esquema, Milvus almacenará los binlogs en columnas.

Binlog data persistence. Persistencia de datos binlog.

Como se ilustra en la imagen anterior, la primera columna es binlog clave primaria. La segunda es la columna timestamp. El resto son las columnas definidas en el esquema. La ruta del archivo de binlogs en MinIO también se indica en la imagen anterior.

Acerca de la serie Deep Dive

Con el anuncio oficial de la disponibilidad general de Milvus 2.0, hemos organizado esta serie de blogs Milvus Deep Dive para ofrecer una interpretación en profundidad de la arquitectura y el código fuente de Milvus. Los temas tratados en esta serie de blogs incluyen

Like the article? Spread the word

Sigue Leyendo