Niveau de cohérence
En tant que base de données vectorielle distribuée, Milvus offre plusieurs niveaux de cohérence pour garantir que chaque nœud ou réplique peut accéder aux mêmes données lors des opérations de lecture et d'écriture. Actuellement, les niveaux de cohérence pris en charge sont Strong, Bounded, Eventually et Session, Bounded étant le niveau de cohérence utilisé par défaut.
Vue d'ensemble
Milvus est un système qui sépare le stockage et le calcul. Dans ce système, les DataNodes sont responsables de la persistance des données et les stockent finalement dans un système de stockage d'objets distribué tel que MinIO/S3. Les QueryNodes s'occupent des tâches de calcul telles que la recherche. Ces tâches impliquent le traitement de données par lots et de données en continu. En termes simples, les données par lots peuvent être considérées comme des données qui ont déjà été stockées dans un système de stockage d'objets, tandis que les données en continu font référence à des données qui n'ont pas encore été stockées dans un système de stockage d'objets. En raison de la latence du réseau, il arrive souvent que les QueryNodes ne détiennent pas les données en continu les plus récentes. Sans garanties supplémentaires, l'exécution d'une recherche directement sur des données en continu peut entraîner la perte de nombreux points de données non validés, ce qui affecte la précision des résultats de la recherche.
Milvus Commercial Edition est un système qui sépare le stockage et le calcul. Dans ce système, les DataNodes sont responsables de la persistance des données et les stockent finalement dans un stockage d'objets distribué tel que MinIO/S3. Les QueryNodes gèrent les tâches de calcul telles que la recherche. Ces tâches impliquent le traitement de données par lots et de données en continu. En termes simples, les données par lots peuvent être considérées comme des données qui ont déjà été stockées dans le stockage d'objets, tandis que les données en continu font référence à des données qui n'ont pas encore été stockées dans le stockage d'objets. En raison de la latence du réseau, il arrive souvent que les QueryNodes ne détiennent pas les données en continu les plus récentes. En l'absence de mesures de protection supplémentaires, l'exécution d'une recherche directement sur des données en continu peut entraîner la perte de nombreux points de données non validés, ce qui affecte la précision des résultats de la recherche.
Données par lots et données en continu
Comme le montre la figure ci-dessus, les QueryNodes peuvent recevoir simultanément des données en continu et des données par lots après avoir reçu une demande de recherche. Toutefois, en raison de la latence du réseau, les données en continu obtenues par les nœuds de requête peuvent être incomplètes.
Pour résoudre ce problème, Milvus horodate chaque enregistrement dans la file d'attente des données et insère continuellement des horodatages de synchronisation dans la file d'attente des données. Chaque fois qu'un horodatage de synchronisation (syncTs) est reçu, QueryNodes le définit comme Heure de service, ce qui signifie que QueryNodes peut voir toutes les données antérieures à cette Heure de service. Sur la base de l'heure de service, Milvus peut fournir des horodatages de garantie (GuaranteeTs) pour répondre aux différentes exigences des utilisateurs en matière de cohérence et de disponibilité. Les utilisateurs peuvent informer les QueryNodes de la nécessité d'inclure des données antérieures à un moment précis dans l'étendue de la recherche en spécifiant des GuaranteeTs dans leurs demandes de recherche.
ServiceTime et GuaranteeTs
Comme le montre la figure ci-dessus, si GuaranteeTs est inférieur à ServiceTime, cela signifie que toutes les données antérieures au moment spécifié ont été entièrement écrites sur le disque, ce qui permet aux QueryNodes d'effectuer immédiatement l'opération de recherche. Lorsque GuaranteeTs est supérieur à ServiceTime, les QueryNodes doivent attendre que ServiceTime dépasse GuaranteeTs avant de pouvoir exécuter l'opération Search.
Les utilisateurs doivent trouver un compromis entre la précision et la latence des requêtes. Si les utilisateurs ont des exigences élevées en matière de cohérence et ne sont pas sensibles à la latence des requêtes, ils peuvent fixer GuaranteeTs à une valeur aussi grande que possible ; si les utilisateurs souhaitent recevoir des résultats de recherche rapidement et sont plus tolérants en matière de précision des requêtes, alors GuaranteeTs peut être fixé à une valeur plus petite.
Illustration des niveaux de cohérence
Milvus propose quatre types de niveaux de cohérence avec différents T de garantie.
Fort
L'horodatage le plus récent est utilisé comme T de garantie, et les nœuds de requête doivent attendre que l'heure de service soit conforme aux T de garantie avant d'exécuter les requêtes de recherche.
Eventuel
La GarantieTs est fixée à une valeur extrêmement faible, telle que 1, afin d'éviter les contrôles de cohérence et de permettre aux nœuds de requête d'exécuter immédiatement des requêtes de recherche sur toutes les données du lot.
Stabilité limitée
La valeur de GuaranteeTs est fixée à un moment antérieur au dernier horodatage pour permettre aux QueryNodes d'effectuer des recherches en tolérant certaines pertes de données.
Session
Le dernier point temporel auquel le client insère des données est utilisé comme GuaranteeTs afin que les QueryNodes puissent effectuer des recherches sur toutes les données insérées par le client.
Milvus utilise Bounded Staleness comme niveau de cohérence par défaut. Si le niveau de garantie n'est pas spécifié, le dernier temps de service est utilisé comme niveau de garantie.
Définir le niveau de cohérence
Vous pouvez définir différents niveaux de cohérence lorsque vous créez une collection ou lorsque vous effectuez des recherches et des requêtes.
Définir le niveau de cohérence lors de la création d'une collection
Lors de la création d'une collection, vous pouvez définir le niveau de cohérence pour les recherches et les requêtes au sein de la collection. L'exemple de code suivant définit le niveau de cohérence à Strong.
client.create_collection(
collection_name="my_collection",
schema=schema,
# highlight-next
consistency_level="Strong",
)
CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
// highlight-next
.consistencyLevel(ConsistencyLevel.STRONG)
.build();
client.createCollection(createCollectionReq);
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "my_id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "my_vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": "5"
}
},
{
"fieldName": "my_varchar",
"dataType": "VarChar",
"isClusteringKey": true,
"elementTypeParams": {
"max_length": 512
}
}
]
}'
export params='{
"consistencyLevel": "Strong"
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"params\": $params
}"
Les valeurs possibles pour le paramètre consistency_level
sont Strong
, Bounded
, Eventually
et Session
.
Définir le niveau de cohérence dans la recherche
Vous pouvez toujours modifier le niveau de cohérence pour une recherche spécifique. L'exemple de code suivant ramène le niveau de cohérence à Bounded. La modification ne s'applique qu'à la demande de recherche en cours.
res = client.search(
collection_name="my_collection",
data=[query_vector],
limit=3,
search_params={"metric_type": "IP"},
# highlight-start
consistency_level="Bounded",
# highlight-next
)
SearchReq searchReq = SearchReq.builder()
.collectionName("my_collection")
.data(Collections.singletonList(queryVector))
.topK(3)
.searchParams(params)
.consistencyLevel(ConsistencyLevel.BOUNDED)
.build();
SearchResp searchResp = client.search(searchReq);
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_collection",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"limit": 3,
"consistencyLevel": "Bounded"
}'
Ce paramètre est également disponible pour les recherches hybrides et l'itérateur de recherche. Les valeurs possibles pour le paramètre consistency_level
sont Strong
, Bounded
, Eventually
et Session
.
Définir le niveau de cohérence dans la requête
Vous pouvez toujours modifier le niveau de cohérence pour une recherche spécifique. L'exemple de code suivant définit le niveau de cohérence sur " Eventuellement". Ce paramètre ne s'applique qu'à la requête en cours.
res = client.query(
collection_name="my_collection",
filter="color like \"red%\"",
output_fields=["vector", "color"],
limit=3,
# highlight-start
consistency_level="Eventually",
# highlight-next
)
QueryReq queryReq = QueryReq.builder()
.collectionName("my_collection")
.filter("color like \"red%\"")
.outputFields(Arrays.asList("vector", "color"))
.limit(3)
.consistencyLevel(ConsistencyLevel.EVENTUALLY)
.build();
QueryResp getResp = client.query(queryReq);
Ce paramètre est également disponible dans l'itérateur de requête. Les valeurs possibles pour le paramètre consistency_level
sont Strong
, Bounded
, Eventually
et Session
.