Milvus
Zilliz
  • Home
  • Blog
  • Choix d'une base de données vectorielle pour la recherche ANN sur Reddit

Choix d'une base de données vectorielle pour la recherche ANN sur Reddit

  • Engineering
November 28, 2025
Chris Fournie

Cet article a été rédigé par Chris Fournie, ingénieur logiciel chez Reddit, et publié à l'origine sur Reddit. Il est reproduit ici avec son autorisation.

En 2024, les équipes de Reddit ont utilisé diverses solutions pour effectuer une recherche vectorielle par approximation du plus proche voisin (ANN). Depuis la recherche vectorielle Vertex AI de Google et l'expérimentation de la recherche vectorielle ANN d'Apache Solr pour certains grands ensembles de données, jusqu'à la bibliothèque FAISS de Facebook pour les petits ensembles de données (hébergés dans des wagons latéraux à échelle verticale). De plus en plus d'équipes de Reddit souhaitaient disposer d'une solution de recherche vectorielle ANN largement supportée, rentable, dotée des fonctionnalités de recherche souhaitées et capable de s'adapter aux données de la taille de Reddit. Pour répondre à ce besoin, nous avons recherché en 2025 la base de données vectorielle idéale pour les équipes de Reddit.

Ce billet décrit le processus que nous avons utilisé pour sélectionner la meilleure base de données vectorielles pour les besoins actuels de Reddit. Il ne décrit pas la meilleure base de données vectorielle en général, ni l'ensemble le plus essentiel d'exigences fonctionnelles et non fonctionnelles pour toutes les situations. Il décrit ce que Reddit et sa culture d'ingénierie ont valorisé et priorisé lors de la sélection d'une base de données vectorielle. Cet article peut servir d'inspiration pour votre propre collecte et évaluation des besoins, mais chaque organisation a sa propre culture, ses propres valeurs et ses propres besoins.

Processus d'évaluation

Globalement, les étapes de sélection ont été les suivantes

1. Recueillir le contexte auprès des équipes

2. Évaluer qualitativement les solutions

3. Évaluer quantitativement les meilleurs candidats

4. Sélection finale

1. Collecte du contexte auprès des équipes

Trois éléments de contexte ont été recueillis auprès des équipes intéressées par la recherche vectorielle ANN :

  • Exigences fonctionnelles (par exemple, recherche vectorielle et lexicale hybride ? Requêtes de recherche par plage ? Filtrage par attributs non vectoriels)

  • Exigences non fonctionnelles (par exemple, peut-il prendre en charge 1B vecteurs ? Peut-il atteindre une latence P99 <100ms ?).

  • Bases de données vectorielles auxquelles les équipes s'intéressaient déjà

Il n'est pas facile d'interroger les équipes sur leurs besoins. Nombre d'entre elles décriront leurs besoins en fonction de la manière dont elles résolvent actuellement un problème, et votre défi consiste à comprendre et à éliminer ce biais.

Par exemple, une équipe utilisait déjà FAISS pour la recherche vectorielle ANN et a déclaré que la nouvelle solution devait renvoyer efficacement 10 000 résultats par appel de recherche. Après discussion, il s'est avéré que la raison de ces 10 000 résultats était qu'ils devaient effectuer un filtrage post hoc et que FAISS ne permettait pas de filtrer les résultats ANN au moment de la requête. Leur problème réel était qu'ils avaient besoin d'un filtrage, donc toute solution offrant un filtrage efficace suffirait, et le renvoi de 10 000 résultats était simplement une solution de contournement nécessaire pour améliorer leur rappel. Dans l'idéal, ils souhaiteraient pré-filtrer l'ensemble de la collection avant de trouver les plus proches voisins.

Il était également utile de demander aux équipes les bases de données vectorielles qu'elles utilisaient déjà ou qui les intéressaient. Si au moins une équipe a une opinion positive de sa solution actuelle, c'est un signe que la base de données vectorielle pourrait être une solution utile à partager dans l'ensemble de l'entreprise. Si les équipes n'ont que des avis négatifs sur une solution, nous ne devrions pas l'inclure comme option. Accepter les solutions qui intéressaient les équipes était aussi un moyen de s'assurer que les équipes se sentaient incluses dans le processus et nous a aidés à former une liste initiale des principaux candidats à évaluer ; il y a trop de solutions de recherche vectorielle ANN dans les bases de données nouvelles et existantes pour les tester toutes de manière exhaustive.

2. Évaluer qualitativement les solutions

À partir de la liste des solutions qui intéressaient les équipes, nous avons évalué qualitativement la solution de recherche vectorielle ANN qui répondait le mieux à nos besoins :

  • recherché chaque solution et évalué la façon dont elle répondait à chaque exigence par rapport à l'importance pondérée de cette exigence

  • éliminé des solutions sur la base de critères qualitatifs et de discussions

  • Nous avons sélectionné les N meilleures solutions pour les tester quantitativement.

Notre liste de départ de solutions de recherche vectorielle ANN incluait :

  • Milvus

  • Qdrant

  • Weviate

  • Open Search

  • Pgvector (utilise déjà Postgres comme SGBDR)

  • Redis (déjà utilisé comme magasin et cache KV)

  • Cassandra (déjà utilisé pour la recherche non-ANN)

  • Solr (déjà utilisé pour la recherche lexicale et expérimenté avec la recherche vectorielle)

  • Vespa

  • Pinecone

  • Vertex AI (déjà utilisé pour la recherche vectorielle ANN)

Nous avons ensuite pris toutes les exigences fonctionnelles et non fonctionnelles mentionnées par les équipes, ainsi que d'autres contraintes représentant nos valeurs et objectifs d'ingénierie, nous les avons inscrites dans une feuille de calcul et nous avons évalué leur importance (de 1 à 3, comme le montre le tableau abrégé ci-dessous).

Pour chaque solution comparée, nous avons évalué (sur une échelle de 0 à 3) dans quelle mesure chaque système répondait à cette exigence (comme le montre le tableau ci-dessous). La notation de cette manière étant quelque peu subjective, nous avons choisi un système et donné des exemples de notes accompagnés d'une justification écrite, et nous avons demandé aux évaluateurs de se référer à ces exemples. Nous avons également donné les indications suivantes pour l'attribution de chaque note : attribuer cette valeur si :

  • 0 : Pas de soutien/preuve de soutien aux exigences

  • 1 : Soutien basique ou inadéquat de l'exigence

  • 2 : Exigence raisonnablement prise en charge

  • 3 : Prise en charge solide de l'exigence qui va au-delà des solutions comparables

Nous avons ensuite créé une note globale pour chaque solution en faisant la somme du produit de la note de l'exigence d'une solution et de l'importance de cette exigence (par exemple, Qdrant a obtenu une note de 3 pour le reclassement/la combinaison des notes, qui a une importance de 2, donc 3 x 2 = 6, répétez cela pour toutes les lignes et faites la somme). Au final, nous obtenons une note globale qui peut être utilisée comme base pour classer et discuter des solutions, et des exigences les plus importantes (notez que la note n'est pas utilisée pour prendre une décision finale, mais comme outil de discussion).

Note de l'éditeur : cet examen était basé sur Milvus 2.4. Nous avons depuis déployé Milvus 2.5, Milvus 2.6, et Milvus 3.0 est sur le point d'arriver, de sorte que certains chiffres peuvent être dépassés. Malgré cela, la comparaison offre toujours de bonnes perspectives et reste très utile.

CatégorieImportanceQdrantMilvus (2.4)CassandraWeviateSolrVertex AI
Type de recherche
Recherche hybride1320222
Recherche par mot-clé1222231
Recherche approximative de NN3332222
Plage de recherche1332200
Re-rangement/combinaison des scores2320221
Méthode d'indexation
HNSW3332220
Prise en charge de plusieurs méthodes d'indexation3031211
Quantification1330300
Hachage sensible à la localité (LSH)100Note : Milvus 2.6 le prend en charge. 0000
Données
Types de vecteurs autres que flottants1220220
Attributs de métadonnées sur les vecteurs (supporte des attributs multiples, une grande taille d'enregistrement, etc.)3322221
Options de filtrage des métadonnées (possibilité de filtrer sur les métadonnées, filtrage avant/après)2322232
Types de données des attributs de métadonnées (schéma robuste, par exemple bool, int, string, json, tableaux)1332231
Limites des attributs de métadonnées (requêtes de plage, par exemple 10 < x < 15)1332221
Diversité des résultats par attribut (par exemple, ne pas obtenir plus de N résultats de chaque subreddit dans une réponse)1212330
Échelle
Centaines de millions d'indices vectoriels323123
Indice vectoriel du milliard122122
Vecteurs de soutien au moins 2k2222211
Vecteurs de support supérieurs à 2k2222111
P95 Latence 50-100ms @ X QPS3222112
P99 Latence <= 10ms @ X QPS3222312
Disponibilité à 99,9 % Récupération2223222
Disponibilité de 99,99 % indexation/stockage2113222
Opérations de stockage
Hébergeable dans AWS3222230
Multi-région1123122
Mises à niveau sans temps d'arrêt1223221
Multi-cloud1333220
APIs/Bibliothèques
gRPC2222202
API RESTful1322212
Aller à la bibliothèque3222212
Bibliothèque Java2222222
Python2222222
Autres langues (C++, Ruby, etc.)1223222
Opérations en cours d'exécution
Mesures Prometheus3222320
Opérations de base de la BD3222222
Insertions2222122
Opérateur Kubernetes2222220
Pagination des résultats2222220
Intégration d'une recherche par ID2222222
Renvoyer les emboîtements avec l'ID du candidat et les scores du candidat1322222
ID fourni par l'utilisateur2222222
Capable d'effectuer des recherches dans un contexte de lots à grande échelle1211212
Sauvegardes / Instantanés : permet de créer des sauvegardes de l'ensemble de la base de données.1222332
Prise en charge efficace des grands index (distinction entre le stockage à froid et le stockage à chaud)1322212
Soutien/Communauté
Neutralité vis-à-vis des fournisseurs3323230
Support api robuste3332222
Soutien aux fournisseurs2222220
Vélocité de la Communauté2322220
Base d'utilisateurs de la production2332212
Sentiment d'appartenance à la communauté1322221
Étoiles Github1222220
Configuration
Traitement des secrets2222122
Source d'information
Source ouverte3333230
Langue2332320
Communiqués de presse2332222
Essais en amont1233222
Disponibilité de la documentation3332121
Coût
Coût Efficace2222221
Performance
Prise en charge de l'optimisation de l'utilisation des ressources pour l'unité centrale, la mémoire et le disque3222222
Mise en commun multi-nœuds (pod)3223222
Avoir la capacité de régler le système pour trouver un équilibre entre la latence et le débit2223222
Partitionnement défini par l'utilisateur (écritures)1323120
Multi-locataires1321322
Cloisonnement2223222
Réplication2223222
Redondance1223222
Basculement automatique320 Note : Milvus 2.6 le prend en charge. 3222
Équilibrage de la charge2223222
Support GPU1020000
QdrantMilvusCassandreWeviateSolrVertex AI
Score global de la solution292281264250242173

Nous avons discuté des notes globales et des notes attribuées aux exigences des différents systèmes et nous avons cherché à comprendre si nous avions correctement pondéré l'importance des exigences et si certaines exigences étaient si importantes qu'elles devaient être considérées comme des contraintes fondamentales. L'une des exigences que nous avons identifiées était de savoir si la solution était open-source ou non, car nous souhaitions une solution dans laquelle nous pourrions nous impliquer, contribuer et résoudre rapidement de petits problèmes si nous en rencontrions à notre échelle. Contribuer et utiliser des logiciels open-source est un élément important de la culture d'ingénierie de Reddit. Les solutions hébergées uniquement (Vertex AI, Pinecone) ont donc été éliminées de notre réflexion.

Au cours des discussions, nous avons constaté que quelques autres exigences clés étaient d'une importance capitale pour nous :

  • Échelle et fiabilité : nous voulions voir des preuves que d'autres entreprises utilisaient la solution avec plus de 100 millions de vecteurs, voire 1 milliard.

  • Communauté : Nous voulions une solution avec une communauté saine et dynamique dans cet espace en pleine évolution.

  • Types de métadonnées et filtrage expressifs pour permettre davantage de cas d'utilisation (filtrage par date, booléen, etc.)

  • Prise en charge de plusieurs types d'index (pas seulement HNSW ou DiskANN) pour mieux adapter les performances à nos nombreux cas d'utilisation uniques.

Le résultat de nos discussions et l'affinement de nos exigences clés nous ont conduits à choisir de tester (dans l'ordre) quantitativement :

  1. Qdrant

  2. Milvus

  3. Vespa, et

  4. Weviate

Malheureusement, de telles décisions prennent du temps et des ressources, et aucune organisation ne dispose d'une quantité illimitée de ces deux éléments. Compte tenu de notre budget, nous avons décidé de tester Qdrant et Milvus, et de laisser les tests de Vespa et Weviate comme objectifs secondaires.

Qdrant vs Milvus était également un test intéressant de deux architectures différentes :

  • Qdrant : Types de nœuds homogènes qui effectuent toutes les opérations de la base de données vectorielles ANN.

  • Milvus : types de nœuds hétérogènes (Milvus ; un pour les requêtes, un autre pour l'indexation, un autre pour l'ingestion de données, un proxy, etc.)

Lequel des deux était facile à configurer (un test de leur documentation) ? Lequel était facile à exécuter (un test de leurs fonctions de résilience et de leur polissage) ? Et lequel était le plus performant pour les cas d'utilisation et l'échelle qui nous intéressaient ? Nous avons cherché à répondre à ces questions en comparant quantitativement les solutions.

3. Évaluer quantitativement les meilleures solutions

Nous voulions mieux comprendre le degré d'évolutivité de chaque solution et, dans la foulée, découvrir ce que seraient l'installation, la configuration, la maintenance et l'exécution de chaque solution à grande échelle. Pour ce faire, nous avons collecté trois ensembles de données de vecteurs de documents et de requêtes pour trois cas d'utilisation différents, configuré chaque solution avec des ressources similaires dans Kubernetes, chargé des documents dans chaque solution et envoyé des charges de requêtes identiques à l'aide de K6 de Grafana avec un exécuteur de taux d'arrivée de montée en puissance pour chauffer les systèmes avant d'atteindre un débit cible (par exemple, 100 QPS).

Nous avons testé le débit, le point de rupture de chaque solution, la relation entre le débit et la latence, et la façon dont ils réagissent à la perte de nœuds sous charge (taux d'erreur, impact sur la latence, etc.). L'effet du filtrage sur la latence était particulièrement intéressant. Nous avons également effectué des tests simples de type oui/non pour vérifier qu'une capacité décrite dans la documentation fonctionnait comme prévu (par exemple, insertions, suppressions, obtention par ID, administration des utilisateurs, etc.

Les tests ont été effectués sur Milvus v2.4 et Qdrant v1.12. En raison de contraintes de temps, nous n'avons pas réglé ou testé de manière exhaustive tous les types de paramètres d'index ; des paramètres similaires ont été utilisés avec chaque solution, avec un biais en faveur d'un rappel ANN élevé, et les tests se sont concentrés sur les performances des index HNSW. Des ressources similaires en termes d'unité centrale et de mémoire ont également été attribuées à chaque solution.

Lors de notre expérimentation, nous avons constaté quelques différences intéressantes entre les deux solutions. Dans les expériences suivantes, chaque solution avait environ 340M Reddit post vectors de 384 dimensions chacun, pour HNSW, M=16, et efConstruction=100.

Dans une expérience, nous avons constaté que pour le même débit de requête (100 QPS sans ingestion en même temps), l'ajout du filtrage affectait la latence de Milvus plus que celle de Qdrant.

Temps de latence des requêtes avec filtrage

Par ailleurs, nous avons constaté qu'il y avait beaucoup plus d'interaction entre l'ingestion et la charge des requêtes sur Qdrant que sur Milvus (illustré ci-dessous à débit constant). Ceci est probablement dû à leur architecture ; Milvus répartit une grande partie de son ingestion sur des types de nœuds distincts de ceux qui servent le trafic de requête, alors que Qdrant sert à la fois l'ingestion et le trafic de requête à partir des mêmes nœuds.

Posts query latency @ 100 QPS during ingest

En testant la diversité des résultats par attribut (par exemple, ne pas obtenir plus de N résultats de chaque subreddit dans une réponse), nous avons constaté que pour le même débit, Milvus avait une latence pire que Qdrant (à 100 QPS).

Temps de latence après la requête et diversité des résultats

Nous avons également voulu voir comment chaque solution s'adaptait à l'ajout de nouvelles répliques de données (c'est-à-dire que le facteur de réplication, RF, passait de 1 à 2). Dans un premier temps, avec RF=1, Qdrant nous a donné une latence satisfaisante pour un débit supérieur à celui de Milvus (le QPS supérieur n'est pas indiqué car les tests ne se sont pas terminés sans erreurs).

Qdrant affiche une latence RF=1 pour un débit variable

Milvus affiche une latence RF=1 pour un débit variable

Cependant, en augmentant le facteur de réplication, la latence p99 de Qdrant s'est améliorée, mais Milvus a pu maintenir un débit plus élevé que Qdrant, avec une latence acceptable (Qdrant 400 QPS non indiqué car le test ne s'est pas terminé en raison d'une latence élevée et d'erreurs).

Milvus affiche une latence RF=2 pour un débit variable.

Qdrant affiche une latence RF=2 pour un débit variable

En raison de contraintes de temps, nous n'avons pas eu le temps de comparer le rappel ANN entre les solutions sur nos ensembles de données, mais nous avons pris en compte les mesures de rappel ANN pour les solutions fournies par https://ann-benchmarks.com/ sur des ensembles de données accessibles au public.

4. Sélection finale

Du point de vue des performances, sans beaucoup de réglages et en utilisant uniquement HNSW, Qdrant a semblé avoir une meilleure latence brute que Milvus dans de nombreux tests. Milvus semblait toutefois mieux s'adapter à une réplication accrue et offrait une meilleure isolation entre l'ingestion et la charge de la requête grâce à son architecture à nœuds multiples.

Sur le plan opérationnel, malgré la complexité de l'architecture de Milvus (plusieurs types de nœuds, dépendant d'un journal d'écriture externe comme Kafka et d'un magasin de métadonnées comme etcd), nous avons eu plus de facilité à déboguer et à réparer Milvus que Qdrant lorsque l'une ou l'autre des solutions s'est retrouvée dans un mauvais état. Milvus dispose également d'un rééquilibrage automatique lors de l'augmentation du facteur de réplication d'une collection, alors que dans Qdrant open-source, la création manuelle ou l'abandon de shards est nécessaire pour augmenter le facteur de réplication (une fonctionnalité que nous aurions dû construire nous-mêmes ou utiliser la version non-open-source).

Milvus est une technologie plus "Reddit" que Qdrant ; elle partage plus de similitudes avec le reste de notre pile technologique. Milvus est écrit en Golang, notre langage de programmation backend préféré, et il est donc plus facile pour nous d'y contribuer que Qdrant, qui est écrit en Rust. Milvus a une excellente vélocité de projet pour son offre open-source par rapport à Qdrant, et il répondait à plus de nos exigences clés.

En fin de compte, les deux solutions ont répondu à la plupart de nos exigences, et dans certains cas, Qdrant avait un avantage en termes de performances, mais nous avons estimé que nous pouvions faire évoluer Milvus davantage, que nous étions plus à l'aise pour l'utiliser, et qu'il correspondait mieux à notre organisation que Qdrant. Nous aurions aimé avoir plus de temps pour tester Vespa et Weaviate, mais ils ont également été sélectionnés pour des raisons d'organisation (Vespa étant basé sur Java) et d'architecture (Weaviate étant de type single-node comme Qdrant).

Principaux enseignements

  • Remettez en question les exigences qui vous sont imposées et essayez d'éliminer les préjugés sur les solutions existantes.

  • Attribuez une note aux solutions candidates et utilisez-la pour éclairer la discussion sur les exigences essentielles, et non pas comme une fin en soi.

  • Évaluez quantitativement les solutions, mais en cours de route, prenez note de ce que c'est que de travailler avec la solution.

  • Choisissez la solution qui convient le mieux à votre organisation du point de vue de la maintenance, des coûts, de la convivialité et des performances, et pas seulement parce qu'elle est la plus performante.

Remerciements

Ce travail d'évaluation a été réalisé par Ben Kochie, Charles Njoroge, Amit Kumar et moi-même. Nous remercions également les autres personnes qui ont contribué à ce travail, notamment Annie Yang, Konrad Reiche, Sabrina Kong et Andrew Johnson, pour la recherche de solutions qualitatives.

Notes de l'éditeur

Nous tenons à remercier sincèrement l'équipe d'ingénieurs de Reddit, non seulement pour avoir choisi Milvus pour leurs charges de travail de recherche vectorielle, mais aussi pour avoir pris le temps de publier une évaluation aussi détaillée et équitable. Il est rare de voir ce niveau de transparence dans la manière dont de véritables équipes d'ingénieurs comparent les bases de données, et leur rapport sera utile à tous les membres de la communauté Milvus (et au-delà) qui essaient de comprendre le paysage croissant des bases de données vectorielles.

Comme Chris le mentionne dans son article, il n'existe pas de "meilleure" base de données vectorielles. Ce qui compte, c'est de savoir si un système correspond à votre charge de travail, à vos contraintes et à votre philosophie opérationnelle. La comparaison de Reddit reflète bien cette réalité. Milvus n'est pas en tête de toutes les catégories, et c'est tout à fait normal étant donné les compromis entre les différents modèles de données et les objectifs de performance.

Une chose mérite d'être clarifiée : L'évaluation de Reddit a utilisé Milvus 2.4, qui était la version stable à l'époque. Certaines fonctionnalités, comme LSH et plusieurs optimisations d'index, n'existaient pas encore ou n'étaient pas mûres dans la version 2.4, de sorte que certains scores reflètent naturellement cette ancienne base de référence. Depuis, nous avons publié Milvus 2.5 puis Milvus 2.6, et c'est un système très différent en termes de performances, d'efficacité et de flexibilité. La réponse de la communauté a été forte et de nombreuses équipes ont déjà procédé à la mise à niveau.

Voici un aperçu des nouveautés de Milvus 2.6 :

  • Jusqu'à 72 % de réduction de l'utilisation de la mémoire et des requêtes 4× plus rapides avec la quantification à 1 bit RaBitQ

  • Réduction des coûts de 50 % grâce au stockage intelligent à plusieurs niveaux

  • Recherche plein texte BM25 4 fois plus rapide qu'Elasticsearch

  • Filtrage JSON 100× plus rapide avec le nouveau Path Index

  • Une nouvelle architecture sans disque pour une recherche plus fraîche à moindre coût

  • Un flux de travail "data-in, data-out" plus simple pour intégrer des pipelines

  • Prise en charge de plus de 100 000 collections pour gérer les grands environnements multi-tenants.

Si vous souhaitez obtenir une analyse complète, voici quelques bonnes informations complémentaires :

Vous avez des questions ou souhaitez approfondir une fonctionnalité ? Rejoignez notre canal Discord ou déposez des questions sur GitHub. Vous pouvez également réserver une session individuelle de 20 minutes pour obtenir des informations, des conseils et des réponses à vos questions dans le cadre des Milvus Office Hours.

    Try Managed Milvus for Free

    Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

    Get Started

    Like the article? Spread the word

    Continuer à Lire