Utiliser mmap
Le mappage de la mémoire (Mmap) permet d'accéder directement à la mémoire des fichiers volumineux sur le disque, ce qui permet à Milvus de stocker des index et des données à la fois dans la mémoire et sur les disques durs. Cette approche permet d'optimiser la politique de placement des données en fonction de la fréquence d'accès, en augmentant la capacité de stockage des collections sans affecter de manière significative les performances de recherche. Cette page vous aide à comprendre comment Milvus utilise mmap pour permettre un stockage et une récupération des données rapides et efficaces.
Vue d'ensemble
Milvus utilise des collections pour organiser les intégrations vectorielles et leurs métadonnées, et chaque ligne de la collection représente une entité. Comme le montre la figure de gauche ci-dessous, le champ vectoriel stocke les intégrations vectorielles et les champs scalaires stockent leurs métadonnées. Lorsque vous avez créé des index sur certains champs et chargé la collection, Milvus charge les index créés et les données brutes des champs dans la mémoire.
Mmap illustré
Milvus est un système de base de données gourmand en mémoire et la taille de la mémoire disponible détermine la capacité d'une collection. Le chargement en mémoire des champs contenant un grand volume de données est impossible si la taille des données dépasse la capacité de la mémoire, ce qui est le cas habituel des applications pilotées par l'IA.
Pour résoudre ces problèmes, Milvus introduit mmap pour équilibrer le chargement des données chaudes et froides dans les collections. Comme le montre la figure de droite ci-dessus, vous pouvez configurer Milvus pour qu'il mette en correspondance les données brutes de certains champs avec la mémoire au lieu de les charger entièrement dans la mémoire. De cette manière, vous pouvez accéder directement aux champs en mémoire sans vous soucier des problèmes de mémoire et étendre la capacité de la collection.
En comparant les procédures de placement des données dans les figures de gauche et de droite, vous pouvez constater que l'utilisation de la mémoire est beaucoup plus importante dans la figure de gauche que dans celle de droite. Lorsque la fonction mmap est activée, les données qui auraient dû être chargées en mémoire sont transférées sur le disque dur et mises en cache dans la mémoire cache du système d'exploitation, ce qui réduit l'encombrement de la mémoire. Toutefois, les échecs de mise en cache peuvent entraîner une dégradation des performances. Pour plus de détails, voir cet article.
Lorsque vous configurez mmap sur Milvus, vous devez toujours respecter un principe : Toujours garder les données et les index fréquemment accédés entièrement chargés dans la mémoire et utiliser mmap pour les champs restants.
Utilisation de mmap dans Milvus
Milvus fournit des paramètres mmap hiérarchiques aux niveaux global, du champ, de l'index et de la collection, les niveaux de l'index et du champ étant prioritaires sur le niveau de la collection, et le niveau de la collection sur le niveau global.
Paramètres mmap globaux
Le paramètre de niveau cluster est le paramètre global et a la priorité la plus faible. Milvus fournit plusieurs paramètres liés au mmap à l'adresse milvus.yaml. Ces paramètres s'appliquent à toutes les collections de la grappe.
...
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
....
Configurer Elément |
Description de l'élément |
Valeur par défaut |
|---|---|---|
|
Spécifie si les données brutes de tous les champs scalaires doivent être mappées dans la mémoire. En définissant ce paramètre sur |
|
|
Spécifie s'il faut mapper tous les index de champs scalaires dans la mémoire. En définissant ce paramètre sur Actuellement, seul le champ scalaire utilisant le type d'index suivant est pris en charge :
|
|
|
Spécifie si les données brutes de tous les champs vectoriels doivent être mises en mémoire. La valeur |
|
|
Spécifie si tous les index des champs vectoriels doivent être mis en mémoire. La valeur Actuellement, seuls les champs vectoriels utilisant les types d'index suivants sont pris en charge :
|
|
|
Indique le chemin d'accès aux fichiers mappés en mémoire. La valeur par défaut s'applique si elle n'est pas spécifiée. L'emplacement |
|
Pour appliquer les paramètres ci-dessus à votre cluster Milvus, veuillez suivre les étapes des sections Configurer Milvus avec Helm et Configurer Milvus avec Milvus Operators.
Parfois, les paramètres mmap globaux ne sont pas flexibles face à des cas d'utilisation particuliers. Pour appliquer d'autres paramètres à une collection spécifique ou à ses index, envisagez de configurer mmap spécifiquement pour une collection, un champ ou un index. Vous devez libérer et charger une collection avant que les modifications apportées aux paramètres mmap ne prennent effet.
Paramètres mmap spécifiques à un champ
Pour configurer l'espace mmap spécifique à un champ, vous devez inclure le paramètre mmap_enabled lorsque vous ajoutez un champ. Vous pouvez activer la fonction mmap pour ce champ spécifique en attribuant à ce paramètre la valeur True.
L'exemple suivant montre comment configurer le mmap spécifique à un champ lors de l'ajout d'un champ.
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" \
--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" \
-d '{
"collectionName": "my_collection",
"fieldName": "doc_chunk",
"fieldParams":{
"mmap.enabled": true
}
}'
Pensez à activer mmap pour les champs qui stockent de gros volumes de données. Les champs scalaires et vectoriels sont pris en charge.
Vous pouvez ensuite créer une collection à l'aide du schéma créé ci-dessus. Lors de la réception d'une demande de chargement de la collection, Milvus utilise la mise en correspondance des données brutes du champ doc_chunk dans la mémoire.
Paramètres mmap spécifiques à l'index
Pour configurer le mmap spécifique à un index, vous devez inclure la propriété mmap.enable dans les paramètres de l'index lorsque vous ajoutez l'index. Vous pouvez activer la fonction mmap sur cet index spécifique en définissant la propriété true.
L'exemple suivant montre comment configurer mmap spécifique à l'index lorsque vous ajoutez un index.
# 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" \
-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" \
-d '{
"collectionName": "my_collection",
"indexName": "doc_chunk",
"properties": {
"mmap.enabled": false
}
}'
Cela s'applique aux index des champs vectoriels et scalaires.
Vous pouvez ensuite référencer les paramètres d'index dans une collection. Lors de la réception d'une demande de chargement de la collection, Milvus met en correspondance l'index du champ titre dans la mémoire.
Paramètres mmap spécifiques à une collection
Pour configurer une stratégie mmap à l'échelle de la collection, vous devez inclure la propriété mmap.enabled dans la demande de création d'une collection. Vous pouvez activer la fonction mmap pour une collection en définissant cette propriété sur true.
L'exemple suivant montre comment activer mmap dans une collection nommée my_collection lors de sa création. Lors de la réception d'une demande de chargement de la collection, Milvus met en correspondance les données brutes de tous les champs dans la mémoire.
# 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" \
--data "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"params\": {
\"mmap.enabled\": \"false\"
}
}"
Vous pouvez également modifier les paramètres mmap d'une collection existante.
# 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" \
-d '{
"collectionName": "my_collection"
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-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" \
-d '{
"collectionName": "my_collection"
}'
Vous devez libérer la collection pour modifier ses propriétés et la recharger pour que les modifications soient prises en compte.