Utilización
Con un procesamiento unificado de lotes y flujos y una arquitectura nativa en la nube, Milvus 2.0 plantea un reto mayor que su predecesor durante el desarrollo de la función DELETE. Gracias a su avanzado diseño de desagregación almacenamiento-computación y al flexible mecanismo de publicación/suscripción, nos enorgullece anunciar que lo hemos conseguido. En Milvus 2.0, puede eliminar una entidad de una colección determinada con su clave primaria, de modo que la entidad eliminada ya no aparecerá en el resultado de una búsqueda o una consulta.
Tenga en cuenta que la operación DELETE en Milvus se refiere a la eliminación lógica, mientras que la limpieza física de datos se produce durante la compactación de datos. El borrado lógico no sólo aumenta enormemente el rendimiento de la búsqueda limitada por la velocidad de E/S, sino que también facilita la recuperación de datos. Los datos borrados lógicamente aún pueden recuperarse con la ayuda de la función Time Travel.
Utilización
Probemos primero la función DELETE en Milvus 2.0. (El siguiente ejemplo utiliza PyMilvus 2.0.0 en Milvus 2.0.0).
from pymilvus import connections, utility, Collection, DataType, FieldSchema, CollectionSchema
# Connect to Milvus
connections.connect(
alias="default",
host='x.x.x.x',
port='19530'
)
# Create a collection with Strong Consistency level
pk_field = FieldSchema(
name="id",
dtype=DataType.INT64,
is_primary=True,
)
vector_field = FieldSchema(
name="vector",
dtype=DataType.FLOAT_VECTOR,
dim=2
)
schema = CollectionSchema(
fields=[pk_field, vector_field],
description="Test delete"
)
collection_name = "test_delete"
collection = Collection(
name=collection_name,
schema=schema,
using='default',
shards_num=2,
consistency_level="Strong"
)
# Insert randomly generated vectors
import random
data = [
[i for i in range(100)],
[[random.random() for _ in range(2)] for _ in range(100)],
]
collection.insert(data)
# Query to make sure the entities to delete exist
collection.load()
expr = "id in [2,4,6,8,10]"
pre_del_res = collection.query(
expr,
output_fields = ["id", "vector"]
)
print(pre_del_res)
# Delete the entities with the previous expression
collection.delete(expr)
# Query again to check if the deleted entities exist
post_del_res = collection.query(
expr,
output_fields = ["id", "vector"]
)
print(post_del_res)
Implementación
En una instancia de Milvus, un nodo de datos es el principal responsable de empaquetar los datos de flujo (registros en el corredor de registros) como datos históricos (instantáneas de registros) y de volcarlos automáticamente al almacenamiento de objetos. Un nodo de consulta ejecuta las peticiones de búsqueda sobre los datos completos, es decir, tanto los datos de flujo como los históricos.
Para aprovechar al máximo la capacidad de escritura de datos de los nodos paralelos de un clúster, Milvus adopta una estrategia de fragmentación basada en hash de clave primaria para distribuir las operaciones de escritura uniformemente entre los distintos nodos de trabajo. Es decir, el proxy dirigirá los mensajes del Lenguaje de Manipulación de Datos (DML) (es decir, las solicitudes) de una entidad al mismo nodo de datos y nodo de consulta. Estos mensajes se publican a través del DML-Channel y son consumidos por el nodo de datos y el nodo de consulta por separado para proporcionar servicios de búsqueda y consulta conjuntamente.
Nodo de datos
Una vez recibidos los mensajes INSERT de datos, el nodo de datos inserta los datos en un segmento creciente, que es un nuevo segmento creado para recibir datos de flujo en memoria. Si el recuento de filas de datos o la duración del segmento creciente alcanza el umbral, el nodo de datos lo sella para impedir la entrada de datos. A continuación, el nodo de datos vacía el segmento sellado, que contiene los datos históricos, en el almacenamiento de objetos. Mientras tanto, el nodo de datos genera un filtro bloom basado en las claves primarias de los nuevos datos, y lo descarga en el almacenamiento de objetos junto con el segmento sellado, guardando el filtro bloom como parte del registro binario de estadísticas (binlog), que contiene la información estadística del segmento.
Un filtro bloom es una estructura de datos probabilística que consta de un vector binario largo y una serie de funciones de asignación aleatoria. Se puede utilizar para comprobar si un elemento es miembro de un conjunto, pero puede devolver falsos positivos. -- Wikipedia
Cuando llegan mensajes DELETE de datos, el nodo de datos almacena en la memoria intermedia todos los filtros bloom del fragmento correspondiente y los compara con las claves primarias proporcionadas en los mensajes para recuperar todos los segmentos (tanto de los crecientes como de los sellados) que posiblemente incluyan las entidades a eliminar. Una vez localizados los segmentos correspondientes, el nodo de datos los almacena en memoria para generar los binlogs Delta que registran las operaciones de borrado y, a continuación, los descarga junto con los segmentos en el almacén de objetos.
Nodo de datos
Dado que un fragmento sólo tiene asignado un canal DML, los nodos de consulta adicionales que se añadan al clúster no podrán suscribirse al canal DML. Para garantizar que todos los nodos de consulta puedan recibir los mensajes DELETE, los nodos de datos filtran los mensajes DELETE del DML-Channel y los reenvían al Delta-Channel para notificar las operaciones de eliminación a todos los nodos de consulta.
Nodo de consulta
Al cargar una colección desde el almacenamiento de objetos, el nodo de consulta obtiene primero el punto de control de cada fragmento, que marca las operaciones DML desde la última operación de vaciado. Basándose en el punto de control, el nodo de consulta carga todos los segmentos sellados junto con sus filtros binlog y bloom Delta. Con todos los datos cargados, el nodo de consulta se suscribe a DML-Channel, Delta-Channel y Query-Channel.
Si llegan más mensajes INSERT de datos después de que la colección se haya cargado en memoria, el nodo de consulta señala primero los segmentos crecientes según los mensajes y actualiza los filtros bloom correspondientes en memoria sólo para fines de consulta. Estos filtros bloom dedicados a la consulta no se vaciarán en el almacenamiento de objetos una vez finalizada la consulta.
Nodo de consulta
Como se ha mencionado anteriormente, sólo un cierto número de nodos de consulta pueden recibir mensajes DELETE del canal DML, lo que significa que sólo ellos pueden ejecutar las peticiones DELETE en segmentos crecientes. Los nodos de consulta que se han suscrito al canal DML filtran primero los mensajes DELETE en los segmentos crecientes, localizan las entidades haciendo coincidir las claves primarias proporcionadas con los filtros bloom dedicados a la consulta de los segmentos crecientes y, a continuación, registran las operaciones de eliminación en los segmentos correspondientes.
Los nodos de consulta que no pueden suscribirse al canal DML sólo pueden procesar solicitudes de búsqueda o consulta en segmentos sellados, ya que sólo pueden suscribirse al canal Delta y recibir los mensajes DELETE enviados por los nodos de datos. Una vez recogidos todos los mensajes DELETE en los segmentos sellados del Delta-Channel, los nodos de consulta localizan las entidades haciendo coincidir las claves primarias proporcionadas con los filtros bloom de los segmentos sellados y, a continuación, registran las operaciones de eliminación en los segmentos correspondientes.
Finalmente, en una búsqueda o consulta, los nodos de consulta generan un conjunto de bits basado en los registros de borrado para omitir las entidades borradas, y buscan entre las entidades restantes de todos los segmentos, independientemente del estado del segmento. Por último, el nivel de coherencia afecta a la visibilidad de los datos eliminados. En el nivel de consistencia fuerte (como se muestra en el ejemplo de código anterior), las entidades eliminadas son invisibles inmediatamente después de la eliminación. Mientras se adopta el Nivel de Consistencia Limitado, habrá varios segundos de latencia antes de que las entidades borradas se vuelvan invisibles.
¿Y ahora qué?
En el blog de la serie de nuevas funciones 2.0, pretendemos explicar el diseño de las nuevas funciones. Más información en esta serie de blogs
- Implementación
- ¿Y ahora qué?
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word