Utilizar mmap
El mapeo de memoria (Mmap) permite el acceso directo en memoria a grandes archivos en disco, permitiendo a Milvus almacenar índices y datos tanto en memoria como en discos duros. Este enfoque ayuda a optimizar la política de colocación de datos basada en la frecuencia de acceso, ampliando la capacidad de almacenamiento de las colecciones sin afectar significativamente al rendimiento de la búsqueda. Esta página le ayuda a entender cómo Milvus utiliza mmap para permitir un almacenamiento y recuperación de datos rápido y eficiente.
Visión general
Milvus utiliza colecciones para organizar las incrustaciones vectoriales y sus metadatos, y cada fila de la colección representa una entidad. Como se muestra en la figura de la izquierda, el campo vectorial almacena las incrustaciones vectoriales, y los campos escalares almacenan sus metadatos. Cuando ha creado índices en ciertos campos y cargado la colección, Milvus carga los índices creados y los datos brutos del campo en la memoria.
Mmap ilustrado
Milvus es un sistema de base de datos intensivo en memoria, y el tamaño de memoria disponible determina la capacidad de una colección. Cargar en memoria campos que contienen un gran volumen de datos es imposible si el tamaño de los datos supera la capacidad de memoria, que es el caso habitual de las aplicaciones basadas en IA.
Para resolver estos problemas, Milvus introduce mmap para equilibrar la carga de datos calientes y fríos en las colecciones. Como se muestra en la figura de arriba a la derecha, puede configurar Milvus para que mapee en memoria los datos sin procesar en ciertos campos en lugar de cargarlos completamente en memoria. De este modo, puede obtener acceso directo a la memoria de los campos sin preocuparse por los problemas de memoria y ampliar la capacidad de la colección.
Comparando los procedimientos de colocación de datos en las figuras de la izquierda y de la derecha, puedes darte cuenta de que el uso de memoria es mucho mayor en la figura de la izquierda que en la de la derecha. Con mmap activado, los datos que deberían haberse cargado en memoria se descargan en el disco duro y se almacenan en caché en la caché de páginas del sistema operativo, lo que reduce la huella de memoria. Sin embargo, los fallos de acierto en la caché pueden provocar una degradación del rendimiento. Para más detalles, consulte este artículo.
Cuando configure mmap en Milvus, siempre hay un principio al que debe adherirse: Mantenga siempre los datos e índices de acceso frecuente totalmente cargados en memoria y utilice mmap para los de los campos restantes.
Utilizar mmap en Milvus
Milvus proporciona configuraciones mmap jerárquicas a nivel global, de campo, de índice y de colección, donde los niveles de índice y de campo tienen prioridad sobre el nivel de colección, y el nivel de colección sobre el nivel global.
Ajustes mmap globales
La configuración a nivel de cluster es la configuración global y tiene la menor precedencia. Milvus proporciona varios ajustes relacionados con mmap en milvus.yaml. Estos ajustes se aplicarán a todas las colecciones del cluster.
...
queryNode:
mmap:
scalarField: false
scalarIndex: false
vectorField: false
vectorIndex: false
# The following should be a path on a high-performance disk
mmapDirPath: any/valid/path
....
Configurar Elemento |
Descripción |
Valor predeterminado |
|---|---|---|
|
Especifica si se asignan los datos brutos de todos los campos escalares a la memoria. Si se establece en |
|
|
Especifica si se asignan todos los índices de campos escalares a la memoria. Si se establece en Actualmente, sólo se admite el campo escalar que utiliza el siguiente tipo de índice:
|
|
|
Especifica si se asignan los datos sin procesar de todos los campos vectoriales a la memoria. Si se establece en |
|
|
Especifica si se asignan todos los índices de los campos vectoriales a la memoria. Si se establece en Actualmente, sólo se soportan los campos vectoriales que utilizan los siguientes tipos de índice:
|
|
|
Especifica la ruta a los archivos mapeados en memoria. Si no se especifica, se aplica el valor por defecto. El marcador de posición |
|
Para aplicar los ajustes anteriores a su cluster Milvus, por favor siga los pasos en Configurar Milvus con Helm y Configurar Milvus con Milvus Operators.
A veces, las configuraciones globales de mmap no son flexibles cuando se enfrentan a casos de uso particulares. Para aplicar ajustes alternativos a una colección específica o a sus índices, considere configurar mmap específico para una colección, un campo o un índice. Es necesario liberar y cargar una colección para que los cambios en la configuración mmap surtan efecto.
Configuración mmap específica de un campo
Para configurar el mmap específico de un campo, debe incluir el parámetro mmap_enabled cuando añada un campo. Puede activar el mmap en este campo específico estableciendo este parámetro en True.
El siguiente ejemplo muestra cómo configurar el mmap específico de campo cuando añades un campo.
from pymilvus import MilvusClient, DataType
CLUSTER_ENDPOINT="http://localhost:19530"
TOKEN="root:Milvus"
client = MilvusClient(
uri=CLUSTER_ENDPOINT,
token=TOKEN
)
schema = MilvusClient.create_schema()
schema.add_field("id", DataType.INT64, is_primary=True, auto_id=False)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=5)
schema = MilvusClient.create_schema()
# Add a scalar field and enable mmap
schema.add_field(
field_name="doc_chunk",
datatype=DataType.INT64,
is_primary=True,
mmap_enabled=True,
)
# Alter mmap settings on a specific field
# The following assumes that you have a collection named `my_collection`
client.alter_collection_field(
collection_name="my_collection",
field_name="doc_chunk",
field_params={"mmap.enabled": True}
)
import io.milvus.param.Constant;
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.*;
import java.util.*;
String CLUSTER_ENDPOINT = "http://localhost:19530";
String TOKEN = "root:Milvus";
client = new MilvusClientV2(ConnectConfig.builder()
.uri(CLUSTER_ENDPOINT)
.token(TOKEN)
.build());
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.autoID(false)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
Map<String, String> typeParams = new HashMap<String, String>() {{
put(Constant.MMAP_ENABLED, "false");
}};
schema.addField(AddFieldReq.builder()
.fieldName("doc_chunk")
.dataType(DataType.VarChar)
.maxLength(512)
.typeParams(typeParams)
.build());
CreateCollectionReq req = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.build();
client.createCollection(req);
client.alterCollectionField(AlterCollectionFieldReq.builder()
.collectionName("my_collection")
.fieldName("doc_chunk")
.property(Constant.MMAP_ENABLED, "true")
.build());
import { MilvusClient, DataType } from '@zilliz/milvus2-sdk-node';
const CLUSTER_ENDPOINT="YOUR_CLUSTER_ENDPOINT";
const TOKEN="YOUR_TOKEN";
const client = await MilvusClient({
address: CLUSTER_ENDPOINT,
token: TOKEN
});
const schema = [
{
name: 'vector',
data_type: DataType.FloatVector
},
{
name: "doc_chunk",
data_type: DataType.VarChar,
max_length: 512,
'mmap.enabled': false,
}
];
await client.createCollection({
collection_name: "my_collection",
schema: schema
});
await client.alterCollectionFieldProperties({
collection_name: "my_collection",
field_name: "doc_chunk",
properties: {"mmap_enable": true}
});
// go
#restful
export TOKEN="root:Milvus"
export CLUSTER_ENDPOINT="http://localhost:19530"
export idField='{
"fieldName": "id",
"dataType": "Int64",
"elementTypeParams": {
"max_length": 512
},
"isPrimary": true,
"auto_id": false
}'
export vectorField='{
"fieldName": "vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": 5
}
}'
export docChunkField='{
"fieldName": "doc_chunk",
"dataType": "Int64",
"elementTypeParams": {
"max_length": 512,
"mmap.enabled": false
}
}'
export schema="{
\"autoID\": false,
\"fields\": [
$idField,
$docChunkField,
$vectorField
]
}"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
--data "{
\"collectionName\": \"my_collection\",
\"schema\": $schema
}"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/fields/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"fieldName": "doc_chunk",
"fieldParams":{
"mmap.enabled": true
}
}'
Considera habilitar mmap para los campos que almacenan datos de gran volumen. Se admiten tanto campos escalares como vectoriales.
A continuación, puede crear una colección utilizando el esquema creado anteriormente. Al recibir una petición para cargar la colección, Milvus utiliza el mapeo en memoria de los datos brutos del campo doc_chunk.
Configuración mmap específica del índice
Para configurar el mmap específico del índice, debe incluir la propiedad mmap.enable en los parámetros del índice cuando añada el índice. Puede activar mmap en este índice específico estableciendo la propiedad en true.
El siguiente ejemplo muestra cómo configurar mmap en un índice específico cuando añades un índice.
# Add a varchar field
schema.add_field(
field_name="title",
datatype=DataType.VARCHAR,
max_length=512
)
index_params = MilvusClient.prepare_index_params()
# Create index on the varchar field with mmap settings
index_params.add_index(
field_name="title",
index_type="AUTOINDEX",
params={ "mmap.enabled": "false" }
)
# Change mmap settings for an index
# The following assumes that you have a collection named `my_collection`
client.alter_index_properties(
collection_name="my_collection",
index_name="title",
properties={"mmap.enabled": True}
)
schema.addField(AddFieldReq.builder()
.fieldName("title")
.dataType(DataType.VarChar)
.maxLength(512)
.build());
List<IndexParam> indexParams = new ArrayList<>();
Map<String, Object> extraParams = new HashMap<String, Object>() {{
put(Constant.MMAP_ENABLED, false);
}};
indexParams.add(IndexParam.builder()
.fieldName("title")
.indexType(IndexParam.IndexType.AUTOINDEX)
.extraParams(extraParams)
.build());
client.alterIndexProperties(AlterIndexPropertiesReq.builder()
.collectionName("my_collection")
.indexName("title")
.property(Constant.MMAP_ENABLED, "true")
.build());
// Create index on the varchar field with mmap settings
await client.createIndex({
collection_name: "my_collection",
field_name: "title",
params: { "mmap.enabled": false }
});
// Change mmap settings for an index
// The following assumes that you have a collection named `my_collection`
await client.alterIndexProperties({
collection_name: "my_collection",
index_name: "title",
properties:{"mmap.enabled": true}
});
// go
# restful
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"indexParams": [
{
"fieldName": "doc_chunk",
"params": {
"index_type": "AUTOINDEX",
"mmap.enabled": true
}
}
]
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"indexName": "doc_chunk",
"properties": {
"mmap.enabled": false
}
}'
Esto se aplica a los índices tanto de campos vectoriales como escalares.
A continuación, puede hacer referencia a los parámetros del índice en una colección. Al recibir una solicitud para cargar la colección, Milvus mapea en memoria el índice del campo de título.
Configuración mmap específica de la colección
Para configurar una estrategia mmap para toda la colección, debe incluir la propiedad mmap.enabled en la solicitud de creación de una colección. Puede activar mmap para una colección estableciendo esta propiedad en true.
El siguiente ejemplo muestra cómo habilitar mmap en una colección llamada mi_colección en el momento de su creación. Al recibir una petición para cargar la colección, Milvus mapea en memoria los datos brutos de todos los campos.
# Enable mmap when creating a collection
client.create_collection(
collection_name="my_collection",
schema=schema,
properties={ "mmap.enabled": "true" }
)
CreateCollectionReq req = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.property(Constant.MMAP_ENABLED, "false")
.build();
client.createCollection(req);
await client.createCollection({
collection_name: "my_collection",
scheme: schema,
properties: { "mmap.enabled": false }
});
// go
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
--data "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"params\": {
\"mmap.enabled\": \"false\"
}
}"
También puede cambiar la configuración mmap de una colección existente.
# Release collection before change mmap settings
client.release_collection("my_collection")
# Ensure that the collection has already been released
# and run the following
client.alter_collection_properties(
collection_name="my_collection",
properties={
"mmap.enabled": false
}
)
# Load the collection to make the above change take effect
client.load_collection("my_collection")
client.releaseCollection(ReleaseCollectionReq.builder()
.collectionName("my_collection")
.build());
client.alterCollectionProperties(AlterCollectionPropertiesReq.builder()
.collectionName("my_collection")
.property(Constant.MMAP_ENABLED, "false")
.build());
client.loadCollection(LoadCollectionReq.builder()
.collectionName("my_collection")
.build());
// Release collection before change mmap settings
await client.releaseCollection({
collection_name: "my_collection"
});
// Ensure that the collection has already been released
// and run the following
await client.alterCollectionProperties({
collection_name: "my_collection",
properties: {
"mmap.enabled": false
}
});
// Load the collection to make the above change take effect
await client.loadCollection({
collection_name: "my_collection"
});
// go
# restful
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/release" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection"
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"properties": {
"mmmap.enabled": false
}
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/load" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection"
}'
Es necesario liberar la colección para realizar cambios en sus propiedades y volver a cargar la colección para que los cambios surtan efecto.