Utilizar Partition Key
La clave de partición es una solución de optimización de la búsqueda basada en particiones. Al designar un campo escalar específico como Clave de Partición y especificar condiciones de filtrado basadas en la Clave de Partición durante la búsqueda, el ámbito de búsqueda puede reducirse a varias particiones, mejorando así la eficiencia de la búsqueda. Este artículo presenta cómo utilizar la Clave de Partición y las consideraciones relacionadas.
Visión general
En Milvus, puede utilizar particiones para implementar la segregación de datos y mejorar el rendimiento de la búsqueda restringiendo el alcance de la búsqueda a particiones específicas. Si elige gestionar las particiones manualmente, puede crear un máximo de 1.024 particiones en una colección, e insertar entidades en estas particiones basándose en una regla específica para que pueda limitar el alcance de la búsqueda restringiendo las búsquedas dentro de un número específico de particiones.
Milvus introduce la Clave de partición para que pueda reutilizar particiones en la segregación de datos para superar el límite en el número de particiones que puede crear en una colección. Al crear una colección, puede utilizar un campo escalar como clave de partición. Una vez que la colección está lista, Milvus crea el número especificado de particiones dentro de la colección. Al recibir una entidad insertada, Milvus calcula un valor hash utilizando el valor de la Clave de Partición de la entidad, ejecuta una operación modulo basada en el valor hash y la propiedad partitions_num de la colección para obtener el ID de la partición de destino, y almacena la entidad en la partición de destino.
Partición Vs Clave de Partición
La siguiente figura ilustra cómo Milvus procesa las peticiones de búsqueda en una colección con o sin la función Partition Key activada.
Si la clave de partición está desactivada, Milvus busca las entidades más similares al vector de consulta dentro de la colección. Puede limitar el alcance de la búsqueda si sabe qué partición contiene los resultados más relevantes.
Si la Clave de Partición está activada, Milvus determina el ámbito de la búsqueda basándose en el valor de la Clave de Partición especificado en un filtro de búsqueda y escanea sólo las entidades dentro de las particiones que coinciden.
Con y Sin Clave de Partición
Usar Clave de Partición
Para utilizar la Clave de Partición, debe
Establecer el número de particiones a crear (Opcional), y
Crear una condición de filtrado basada en la Clave de Partición.
Establecer la Clave de Partición
Para designar un campo escalar como Clave de Partición, necesita establecer su atributo is_partition_key a true cuando añada el campo escalar.
Cuando estableces un campo escalar como Clave de Partición, los valores del campo no pueden estar vacíos o ser nulos.
from pymilvus import (
MilvusClient, DataType
)
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
schema = client.create_schema()
schema.add_field(field_name="id",
datatype=DataType.INT64,
is_primary=True)
schema.add_field(field_name="vector",
datatype=DataType.FLOAT_VECTOR,
dim=5)
# Add the partition key
schema.add_field(
field_name="my_varchar",
datatype=DataType.VARCHAR,
max_length=512,
is_partition_key=True,
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build());
// Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
// Add the partition key
schema.addField(AddFieldReq.builder()
.fieldName("my_varchar")
.dataType(DataType.VarChar)
.maxLength(512)
.isPartitionKey(true)
.build());
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v2/column"
"github.com/milvus-io/milvus/client/v2/entity"
"github.com/milvus-io/milvus/client/v2/index"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
milvusAddr := "localhost:19530"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: milvusAddr,
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
defer client.Close(ctx)
schema := entity.NewSchema().WithDynamicFieldEnabled(false)
schema.WithField(entity.NewField().
WithName("id").
WithDataType(entity.FieldTypeInt64).
WithIsPrimaryKey(true),
).WithField(entity.NewField().
WithName("my_varchar").
WithDataType(entity.FieldTypeVarChar).
WithIsPartitionKey(true).
WithMaxLength(512),
).WithField(entity.NewField().
WithName("vector").
WithDataType(entity.FieldTypeFloatVector).
WithDim(5),
)
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});
// 3. Create a collection in customized setup mode
// 3.1 Define fields
const fields = [
{
name: "my_varchar",
data_type: DataType.VarChar,
max_length: 512,
is_partition_key: true
}
]
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": "5"
}
},
{
"fieldName": "my_varchar",
"dataType": "VarChar",
"isPartitionKey": true,
"elementTypeParams": {
"max_length": 512
}
}
]
}'
Establecer Números de Partición
Cuando designa un campo escalar en una colección como Clave de Partición, Milvus crea automáticamente 16 particiones en la colección. Al recibir una entidad, Milvus elige una partición basándose en el valor de la Clave de Partición de esta entidad y almacena la entidad en la partición, dando como resultado que algunas o todas las particiones contengan entidades con diferentes valores de Clave de Partición.
También puede determinar el número de particiones a crear junto con la colección. Esto sólo es válido si tienes un campo escalar designado como Clave de Partición.
client.create_collection(
collection_name="my_collection",
schema=schema,
num_partitions=128
)
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.numPartitions(128)
.build();
client.createCollection(createCollectionReq);
err = client.CreateCollection(ctx,
milvusclient.NewCreateCollectionOption("my_collection", schema).
WithNumPartitions(128))
if err != nil {
fmt.Println(err.Error())
// handle error
}
await client.create_collection({
collection_name: "my_collection",
schema: schema,
num_partitions: 128
})
export params='{
"partitionsNum": 128
}'
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"params\": $params
}"
Crear condición de filtrado
Al realizar búsquedas RNA en una colección con la función Clave de partición activada, debe incluir una expresión de filtrado que incluya la Clave de partición en la solicitud de búsqueda. En la expresión de filtrado, puede restringir el valor de la Clave de Partición dentro de un rango específico para que Milvus restrinja el ámbito de búsqueda dentro de las particiones correspondientes.
Al realizar operaciones de borrado, es aconsejable incluir una expresión de filtrado que especifique una única clave de partición para conseguir un borrado más eficiente. Este enfoque limita la operación de borrado a una partición en particular, reduciendo la amplificación de escritura durante la compactación y conservando recursos para la compactación y la indexación.
Los siguientes ejemplos demuestran el filtrado basado en Clave de Partición basado en un valor específico de Clave de Partición y un conjunto de valores de Clave de Partición.
# Filter based on a single partition key value, or
filter='partition_key == "x" && <other conditions>'
# Filter based on multiple partition key values
filter='partition_key in ["x", "y", "z"] && <other conditions>'
// Filter based on a single partition key value, or
String filter = "partition_key == 'x' && <other conditions>";
// Filter based on multiple partition key values
String filter = "partition_key in ['x', 'y', 'z'] && <other conditions>";
// Filter based on a single partition key value, or
filter = "partition_key == 'x' && <other conditions>"
// Filter based on multiple partition key values
filter = "partition_key in ['x', 'y', 'z'] && <other conditions>"
// Filter based on a single partition key value, or
const filter = 'partition_key == "x" && <other conditions>'
// Filter based on multiple partition key values
const filter = 'partition_key in ["x", "y", "z"] && <other conditions>'
# Filter based on a single partition key value, or
export filter='partition_key == "x" && <other conditions>'
# Filter based on multiple partition key values
export filter='partition_key in ["x", "y", "z"] && <other conditions>'
Debe sustituir partition_key por el nombre del campo designado como clave de partición.
Utilizar el Aislamiento de la Clave de Partición
En el escenario multi-tenancy, puede designar el campo escalar relacionado con las identidades de los tenants como la clave de partición y crear un filtro basado en un valor específico en este campo escalar. Para mejorar aún más el rendimiento de la búsqueda en escenarios similares, Milvus introduce la función Aislamiento de clave de partición.
Aislamiento de la clave de partición
Como se muestra en la figura anterior, Milvus agrupa las entidades basándose en el valor de la clave de partición y crea un índice separado para cada uno de estos grupos. Al recibir una petición de búsqueda, Milvus localiza el índice basado en el valor de la Clave de Partición especificado en la condición de filtrado y restringe el ámbito de búsqueda dentro de las entidades incluidas en el índice, evitando así escanear entidades irrelevantes durante la búsqueda y mejorando enormemente el rendimiento de la búsqueda.
Una vez que haya habilitado el Aislamiento de Clave de Partición, debe incluir sólo un valor específico en el filtro basado en Clave de Partición para que Milvus pueda restringir el ámbito de búsqueda dentro de las entidades incluidas en el índice que coincidan.
Actualmente, la función de Aislamiento de Clave de Partición sólo se aplica a las búsquedas con el tipo de índice establecido en HNSW.
Activación del aislamiento de claves de partición
Los siguientes ejemplos de código demuestran cómo habilitar el Aislamiento de Claves de Partición.
client.create_collection(
collection_name="my_collection",
schema=schema,
properties={"partitionkey.isolation": True}
)
import io.milvus.v2.service.collection.request.CreateCollectionReq;
Map<String, String> properties = new HashMap<>();
properties.put("partitionkey.isolation", "true");
CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.properties(properties)
.build();
client.createCollection(createCollectionReq);
err = client.CreateCollection(ctx,
milvusclient.NewCreateCollectionOption("my_collection", schema).
WithProperty("partitionkey.isolation", true))
if err != nil {
fmt.Println(err.Error())
// handle error
}
res = await client.alterCollection({
collection_name: "my_collection",
properties: {
"partitionkey.isolation": true
}
})
export params='{
"partitionKeyIsolation": true
}'
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"params\": $params
}"
Una vez que haya habilitado el Aislamiento de Claves de Partición, aún puede establecer la Clave de Partición y el número de particiones como se describe en Establecer Números de Partición. Tenga en cuenta que el filtro basado en la Clave de Partición debe incluir sólo un valor específico de Clave de Partición.