Diagnostiquer un problème
Il y a plusieurs raisons possibles à une dégradation des performances de recherche. Les plus courantes sont :
- Pression mémoire : si l'ensemble de travail dépasse la RAM disponible
- Requêtes complexes (par exemple,
hnsw_efélevé, filtres complexes sans index de payload) - Processus d'arrière-plan concurrents (par exemple, optimizer toujours en cours d'exécution après un chargement en masse)
- Problème avec le cluster (par exemple, problèmes réseau, dégradation matérielle)
Requête unique trop lente (Latence)
À utiliser quand : les requêtes individuelles prennent trop de temps indépendamment de la charge.
Étapes de diagnostic :
- Vérifier si la deuxième exécution de la même requête est significativement plus rapide (indique une pression mémoire)
- Essayer la même requête avec
with_payload: falseetwith_vectors: falsepour voir si la récupération de payload est le goulot d'étranglement - Si la requête utilise des filtres, essayer de les supprimer un par un pour identifier si une condition de filtre spécifique est le goulot d'étranglement
Corrections courantes :
- Affiner les paramètres HNSW : Fine-tuning search
- Activer la quantization en mémoire : Scalar quantization
- Réduire la dimensionnalité vectorielle avec les modèles Matryoshka : Matryoshka Models
- Utiliser le suréchatillonnage + rescore pour les vecteurs haute dimensionnelle Search with quantization
- Activer io_uring pour les charges de travail intensives en disque sur Linux io_uring
Impossible de gérer suffisamment de QPS (Débit)
À utiliser quand : le système ne peut pas servir suffisamment de requêtes par seconde sous charge.
- Réduire le nombre de segments (
default_segment_numberà 2) Maximizing throughput - Utiliser l'API de recherche par lot au lieu de requêtes uniques Batch search
- Activer la quantization pour réduire le coût CPU Scalar quantization
- Ajouter des répliques pour distribuer la charge de lecture Replication
La recherche filtrée est lente
À utiliser quand : la recherche filtrée est significativement plus lente que la recherche non filtrée. Plainte SA la plus courante après la mémoire.
- Créer un index de payload sur le champ filtré Payload index
- Utiliser
is_tenant=truepour la condition de filtrage principale : Tenant index - Essayer l'algorithme ACORN pour les filtres complexes : ACORN
- Éviter d'utiliser les conditions de filtrage
nestedcomme filtre principal. Cela pourrait forcer qdrant à lire les valeurs de payload brutes au lieu d'utiliser l'index. - Si l'index de payload a été ajouté après la construction de HNSW, déclencher une réindexation pour créer les liens de sous-graphe filtrables
Optimiser les performances de recherche avec les mises à jour parallèles
Étapes de diagnostic
- Essayer d'exécuter la même requête avec le paramètre
indexed_only=true, si la requête est significativement plus rapide, cela signifie que l'optimizer est toujours en cours d'exécution et n'a pas encore indexé tous les segments. - Si l'utilisation CPU ou IO est élevée même sans requêtes, cela indique également que l'optimizer est toujours en cours d'exécution.
Modifications de configuration recommandées
- Réduire
optimizer_cpu_budgetpour réserver plus de CPU pour les requêtes - Utiliser
prevent_unoptimized=truepour empêcher la création de segments avec une grande quantité de données non indexées pour les recherches. À la place, une fois qu'un segment atteint le seuil appelé indexing_threshold, tous les points supplémentaires seront ajoutés en « deferred state ».
En savoir plus ici
Ce qu'il NE FAUT PAS faire
- Définir
always_ram=falsesur la quantization (thrashing disque à chaque recherche) - Mettre HNSW sur disque pour la production sensible à la latence (uniquement pour le stockage froid)
- Augmenter le nombre de segments pour le débit (au contraire : moins = mieux)
- Créer des index de payload sur chaque champ (gaspille de la mémoire)
- Blâmer Qdrant avant de vérifier l'état de l'optimizer