Milvus
Zilliz
  • Home
  • Blog
  • Escolher uma base de dados de vectores para a pesquisa ANN no Reddit

Escolher uma base de dados de vectores para a pesquisa ANN no Reddit

  • Engineering
November 28, 2025
Chris Fournie

Este post foi escrito por Chris Fournie, o engenheiro de software da equipa do Reddit, e publicado originalmente no Reddit, e é republicado aqui com permissão.

Em 2024, as equipas do Reddit utilizaram uma variedade de soluções para realizar a pesquisa vetorial aproximada do vizinho mais próximo (ANN). Desde a pesquisa de vectores Vertex AI da Google e a experimentação da pesquisa de vectores ANN do Apache Solr para alguns conjuntos de dados maiores, até à biblioteca FAISS do Facebook para conjuntos de dados mais pequenos (alojados em carros laterais de escala vertical). Cada vez mais equipes do Reddit queriam uma solução de pesquisa vetorial ANN com amplo suporte, que fosse econômica, tivesse os recursos de pesquisa desejados e pudesse ser dimensionada para dados do tamanho do Reddit. Para atender a essa necessidade, em 2025, procuramos o banco de dados vetorial ideal para as equipes do Reddit.

Este post descreve o processo que usamos para selecionar o melhor banco de dados vetorial para as necessidades atuais do Reddit. Não descreve a melhor base de dados vetorial em geral, nem o conjunto mais essencial de requisitos funcionais e não funcionais para todas as situações. Ele descreve o que o Reddit e sua cultura de engenharia valorizaram e priorizaram ao selecionar um banco de dados vetorial. Esta publicação pode servir de inspiração para a sua própria recolha e avaliação de requisitos, mas cada organização tem a sua própria cultura, valores e necessidades.

Processo de avaliação

No geral, as etapas de seleção foram:

1. Recolher o contexto das equipas

2. Avaliar qualitativamente as soluções

3. Avaliar quantitativamente os melhores candidatos

4. Seleção final

1. Recolher o contexto das equipas

Foram recolhidos três elementos de contexto das equipas interessadas em realizar a pesquisa vetorial ANN:

  • Requisitos funcionais (por exemplo, pesquisa híbrida vetorial e lexical? Consultas de pesquisa de intervalo? Filtragem por atributos não vectoriais?)

  • Requisitos não funcionais (por exemplo, pode suportar vetores 1B? Pode atingir uma latência <100ms P99?)

  • As equipas de bases de dados vectoriais já estavam interessadas

Entrevistar equipas para obter requisitos não é trivial. Muitos descreverão suas necessidades em termos de como estão resolvendo um problema atualmente, e seu desafio é entender e remover esse viés.

Por exemplo, uma equipa já estava a utilizar o FAISS para a pesquisa de vectores ANN e afirmou que a nova solução deve devolver eficientemente 10K resultados por chamada de pesquisa. Após uma discussão mais aprofundada, a razão para os 10K resultados era que precisavam de efetuar uma filtragem post-hoc, e o FAISS não oferece filtragem de resultados ANN no momento da consulta. O problema real era que precisavam de filtragem, pelo que qualquer solução que oferecesse uma filtragem eficiente seria suficiente, e o envio de 10 mil resultados era simplesmente uma solução alternativa necessária para melhorar a sua recordação. Idealmente, gostariam de pré-filtrar toda a coleção antes de encontrar os vizinhos mais próximos.

Pedir as bases de dados de vectores que as equipas já utilizavam ou nas quais estavam interessadas também foi útil. Se pelo menos uma equipa tiver uma opinião positiva sobre a sua solução atual, é um sinal de que a base de dados vetorial pode ser uma solução útil a partilhar por toda a empresa. Se as equipas só tiverem opiniões negativas sobre uma solução, então não a devemos incluir como opção. Aceitar soluções em que as equipas estavam interessadas foi também uma forma de garantir que as equipas se sentiam incluídas no processo e ajudou-nos a formar uma lista inicial dos principais candidatos a avaliar; existem demasiadas soluções de pesquisa vetorial ANN em bases de dados novas e existentes para as testar exaustivamente.

2. Avaliar qualitativamente as soluções

Começando com a lista de soluções em que as equipas estavam interessadas, para avaliar qualitativamente qual a solução de pesquisa vetorial ANN que melhor se adequava às nossas necessidades, nós:

  • Pesquisámos cada solução e classificámos o seu grau de cumprimento de cada requisito em função da importância ponderada desse requisito

  • Removemos soluções com base em critérios qualitativos e discussão

  • Selecionámos as N melhores soluções para testar quantitativamente

A nossa lista inicial de soluções de pesquisa vetorial ANN incluía

  • Milvus

  • Qdrant

  • Weviate

  • Pesquisa aberta

  • Pgvector (já utilizava Postgres como RDBMS)

  • Redis (já utilizado como armazenamento e cache de KV)

  • Cassandra (já utilizado para pesquisa não-ANA)

  • Solr (já utilizado para pesquisa lexical e experimentado com pesquisa vetorial)

  • Vespa

  • Pinecone

  • Vertex AI (já utilizado para pesquisa vetorial ANN)

Em seguida, pegámos em todos os requisitos funcionais e não funcionais mencionados pelas equipas, mais algumas restrições que representavam os nossos valores e objectivos de engenharia, criámos essas linhas numa folha de cálculo e avaliámos a sua importância (de 1 a 3; apresentada na tabela resumida abaixo).

Para cada solução que estávamos a comparar, avaliámos (numa escala de 0 a 3) até que ponto cada sistema satisfazia esse requisito (como se mostra na tabela abaixo). A pontuação desta forma era algo subjectiva, pelo que escolhemos um sistema e demos exemplos de pontuações com uma justificação escrita e pedimos aos revisores que se referissem a esses exemplos. Também demos a seguinte orientação para a atribuição de cada valor de pontuação: atribuir este valor se:

  • 0: Sem suporte/evidência de suporte a requisitos

  • 1: Suporte básico ou inadequado do requisito

  • 2: Requisito razoavelmente suportado

  • 3: Suporte robusto de requisitos que vai além de soluções comparáveis

Em seguida, criamos uma pontuação geral para cada solução, obtendo a soma do produto da pontuação do requisito de uma solução e a importância desse requisito (por exemplo, Qdrant obteve pontuação 3 para reclassificação/combinação de pontuação, que tem importância 2, então 3 x 2 = 6, repita isso para todas as linhas e some tudo). No final, temos uma pontuação geral que pode ser usada como base para classificar e discutir soluções, e quais requisitos são mais importantes (observe que a pontuação não é usada para tomar uma decisão final, mas como uma ferramenta de discussão).

Nota do editor: Esta análise foi baseada no Milvus 2.4. Desde então, lançámos o Milvus 2.5, o Milvus 2.6 e o Milvus 3.0 está mesmo ao virar da esquina, pelo que alguns números podem estar desactualizados. Mesmo assim, a comparação continua a oferecer uma boa visão e continua a ser muito útil.

CategoriaImportânciaQdrantMilvus (2.4)CassandraWeviateSolrVertex AI
Tipo de pesquisa
Pesquisa híbrida1320222
Pesquisa por palavra-chave1222231
Pesquisa NN aproximada3332222
Pesquisa de alcance1332200
Rearranjo/combinação de pontuação2320221
Método de indexação
HNSW3332220
Suporta múltiplos métodos de indexação3031211
Quantização1330300
Agrupamento sensível à localidade (LSH)100Nota: Milvus 2.6 suporta-o. 0000
Dados
Tipos de vectores diferentes de float1220220
Atributos de metadados em vectores (suporta múltiplos atributos, um tamanho de registo grande, etc.)3322221
Opções de filtragem de metadados (pode filtrar metadados, tem filtragem pré/pós)2322232
Tipos de dados de atributos de metadados (esquema robusto, por exemplo, bool, int, string, json, arrays)1332231
Limites de atributos de metadados (consultas de intervalo, por exemplo, 10 < x < 15)1332221
Diversidade de resultados por atributo (por exemplo, obter não mais de N resultados de cada subreddit numa resposta)1212330
Escala
Centenas de milhões de índices vectoriais323123
Índice vetorial do bilião122122
Vectores de apoio com pelo menos 2k2222211
Vectores de suporte superiores a 2k2222111
P95 Latência 50-100ms @ X QPS3222112
P99 Latência <= 10ms @ X QPS3222312
99,9% de disponibilidade recuperação2223222
99,99% de disponibilidade de indexação/armazenamento2113222
Operações de armazenamento
Hospedável no AWS3222230
Multi-região1123122
Actualizações com tempo de inatividade zero1223221
Múltiplas nuvens1333220
APIs/Bibliotecas
gRPC2222202
API RESTful1322212
Ir para a biblioteca3222212
Biblioteca Java2222222
Python2222222
Outras línguas (C++, Ruby, etc.)1223222
Operações em tempo de execução
Métricas do Prometheus3222320
Operações básicas de BD3222222
Sobreposições2222122
Operador de Kubernetes2222220
Paginação dos resultados2222220
Incorporação da pesquisa por ID2222222
Devolver Embeddings com ID do candidato e pontuações do candidato1322222
ID fornecido pelo utilizador2222222
Capaz de pesquisar em contexto de lote em grande escala1211212
Cópias de segurança / Instantâneos: suporta a capacidade de criar cópias de segurança de toda a base de dados1222332
Suporte eficiente de grandes índices (distinção entre armazenamento frio e quente)1322212
Apoio/Comunidade
Neutralidade do fornecedor3323230
Suporte robusto da API3332222
Apoio do fornecedor2222220
Velocidade da Comunidade2322220
Base de utilizadores de produção2332212
Sentimento da comunidade1322221
Estrelas do Github1222220
Configuração
Tratamento de segredos2222122
Fonte
Fonte aberta3333230
Língua2332320
Lançamentos2332222
Ensaios a montante1233222
Disponibilidade de documentação3332121
Custo
Custo efetivo2222221
Desempenho
Suporte para ajustar a utilização de recursos para CPU, memória e disco3222222
Fragmentação de vários nós (pod)3223222
Ter a capacidade de ajustar o sistema para equilibrar a latência e o débito2223222
Partição definida pelo utilizador (escritas)1323120
Multi-tenant1321322
Partição2223222
Replicação2223222
Redundância1223222
Failover automático320 Nota: Milvus 2.6 suporta-o. 3222
Balanceamento de carga2223222
Suporte de GPU1020000
QdrantMilvusCassandraWeviateSolrVertex AI
Pontuações globais da solução292281264250242173

Discutimos as pontuações globais e dos requisitos dos vários sistemas e procurámos perceber se tínhamos ponderado adequadamente a importância dos requisitos e se alguns requisitos eram tão importantes que deviam ser considerados restrições fundamentais. Um desses requisitos que identificámos foi o facto de a solução ser ou não de código aberto, porque desejávamos uma solução com a qual nos pudéssemos envolver, contribuir e resolver rapidamente pequenos problemas se os tivéssemos na nossa escala. Contribuir e utilizar software de código aberto é uma parte importante da cultura de engenharia do Reddit. Isso eliminou as soluções somente hospedadas (Vertex AI, Pinecone) de nossa consideração.

Durante as discussões, descobrimos que alguns outros requisitos-chave eram de grande importância para nós:

  • Escala e confiabilidade: queríamos ver evidências de outras empresas executando a solução com mais de 100 milhões ou até 1 bilhão de vetores

  • Comunidade: Queríamos uma solução com uma comunidade saudável e com muito dinamismo neste espaço em rápido amadurecimento

  • Tipos de metadados e filtragem expressivos para permitir mais dos nossos casos de utilização (filtragem por data, booleana, etc.)

  • Suporte para vários tipos de índices (não apenas HNSW ou DiskANN) para melhor adequar o desempenho aos nossos muitos casos de uso exclusivos

O resultado das nossas discussões e do aperfeiçoamento dos principais requisitos levou-nos a optar por testar (por ordem) quantitativamente:

  1. Qdrant

  2. Milvus

  3. Vespa, e

  4. Weviate

Infelizmente, decisões como esta requerem tempo e recursos, e nenhuma organização dispõe de quantidades ilimitadas de ambos. Dado o nosso orçamento, decidimos testar o Qdrant e o Milvus e deixar os testes do Vespa e do Weviate como objectivos ambiciosos.

Qdrant vs Milvus foi também um teste interessante de duas arquitecturas diferentes:

  • Qdrant: Tipos de nós homogéneos que executam todas as operações da base de dados vetorial ANN

  • Milvus: tipos de nós heterogéneos (Milvus; um para consultas, outro para indexação, outro para ingestão de dados, um proxy, etc.)

Qual deles foi mais fácil de configurar (um teste da sua documentação)? Qual deles foi fácil de executar (um teste das suas caraterísticas de resiliência e polimento)? E qual deles teve o melhor desempenho para os casos de uso e a escala que nos interessava? Procurámos responder a estas perguntas ao comparar quantitativamente as soluções.

3. Avaliar quantitativamente os principais concorrentes

Queríamos entender melhor a escalabilidade de cada solução e, no processo, experimentar como seria instalar, configurar, manter e executar cada solução em escala. Para fazer isso, coletamos três conjuntos de dados de vetores de documentos e consultas para três casos de uso diferentes, configuramos cada solução com recursos semelhantes no Kubernetes, carregamos documentos em cada solução e enviamos cargas de consulta idênticas usando o K6 do Grafana com um executor de taxa de chegada em rampa para aquecer os sistemas antes de atingir uma taxa de transferência de destino (por exemplo, 100 QPS).

Testamos a taxa de transferência, o ponto de rutura de cada solução, a relação entre taxa de transferência e latência e como eles reagem à perda de nós sob carga (taxa de erro, impacto na latência etc.). De grande interesse foi o efeito da filtragem na latência. Também fizemos testes simples de sim/não para verificar se uma capacidade na documentação funcionava como descrito (por exemplo, upserts, delete, get by ID, administração de utilizadores, etc.) e para experimentar a ergonomia dessas APIs.

Os testes foram efectuados no Milvus v2.4 e no Qdrant v1.12. Devido a limitações de tempo, não afinámos nem testámos exaustivamente todos os tipos de definições de índices; foram utilizadas definições semelhantes em cada solução, com uma tendência para uma elevada recuperação de ANN, e os testes centraram-se no desempenho dos índices HNSW. Também foram atribuídos recursos de CPU e memória semelhantes a cada solução.

Na nossa experimentação, encontrámos algumas diferenças interessantes entre as duas soluções. Nas experiências seguintes, cada solução tinha aproximadamente 340M Reddit post vectors de 384 dimensões cada, para HNSW, M=16, e efConstruction=100.

Numa experiência, verificámos que, para o mesmo débito de consulta (100 QPS sem ingestão ao mesmo tempo), a adição de filtragem afectou mais a latência do Milvus do que do Qdrant.

Latência de consulta de posts com filtragem

Em outra, descobrimos que havia muito mais interação entre ingestão e carga de consulta na Qdrant do que na Milvus (mostrada abaixo com taxa de transferência constante). Isto deve-se provavelmente à sua arquitetura; a Milvus divide grande parte da sua ingestão em tipos de nós separados daqueles que servem o tráfego de consulta, enquanto a Qdrant serve tanto a ingestão como o tráfego de consulta a partir dos mesmos nós.

Latência de consulta de posts a 100 QPS durante a ingestão

Ao testar a diversidade de resultados por atributo (por exemplo, obter não mais que N resultados de cada subreddit em uma resposta), descobrimos que, para a mesma taxa de transferência, o Milvus tinha latência pior que o Qdrant (a 100 QPS).

Latência de pós-consulta com diversidade de resultados

Também queríamos ver a eficácia de cada solução quando mais réplicas de dados foram adicionadas (ou seja, o fator de replicação, RF, foi aumentado de 1 para 2). Inicialmente, olhando para RF=1, Qdrant foi capaz de nos dar uma latência satisfatória para mais rendimento do que Milvus (QPS mais alto não mostrado porque os testes não foram concluídos sem erros).

Qdrant apresenta latência RF=1 para taxa de transferência variável

Milvus apresenta latência RF=1 para taxa de transferência variável

No entanto, ao aumentar o fator de replicação, a latência do p99 do Qdrant melhorou, mas o Milvus conseguiu manter um throughput maior do que o do Qdrant, com latência aceitável (Qdrant 400 QPS não mostrado porque o teste não foi concluído devido à alta latência e aos erros).

Milvus apresenta latência RF=2 para taxa de transferência variável

Qdrant apresenta latência RF=2 para taxa de transferência variável

Devido a restrições de tempo, não tivemos tempo suficiente para comparar a recuperação de RNA entre soluções nos nossos conjuntos de dados, mas tivemos em conta as medições de recuperação de RNA para soluções fornecidas por https://ann-benchmarks.com/ em conjuntos de dados publicamente disponíveis.

4. Seleção final

Em termos de desempenho, sem muitos ajustes e usando apenas o HNSW, o Qdrant pareceu ter melhor latência bruta em muitos testes do que o Milvus. No entanto, a Milvus parecia escalar melhor com o aumento da replicação e tinha um melhor isolamento entre a ingestão e a carga de consulta devido à sua arquitetura de múltiplos nós.

Em termos de operação, apesar da complexidade da arquitetura do Milvus (vários tipos de nós, dependente de um registo externo de escrita antecipada como o Kafka e um armazenamento de metadados como o etcd), tivemos mais facilidade em depurar e corrigir o Milvus do que o Qdrant quando qualquer uma das soluções entrou em mau estado. O Milvus também tem um reequilíbrio automático quando se aumenta o fator de replicação de uma coleção, enquanto que no Qdrant de código aberto é necessário criar manualmente ou eliminar fragmentos para aumentar o fator de replicação (uma funcionalidade que teríamos de construir nós próprios ou utilizar a versão de código não aberto).

O Milvus é uma tecnologia mais "Reddit-shaped" do que o Qdrant; partilha mais semelhanças com o resto da nossa pilha tecnológica. O Milvus é escrito em Golang, a nossa linguagem de programação de backend preferida, e por isso é mais fácil para nós contribuirmos do que o Qdrant, que é escrito em Rust. A Milvus tem uma excelente velocidade de projeto para a sua oferta de código aberto em comparação com a Qdrant, e satisfez mais dos nossos principais requisitos.

No final, ambas as soluções atenderam à maioria dos nossos requisitos e, em alguns casos, a Qdrant teve uma vantagem de desempenho, mas sentimos que poderíamos escalar mais a Milvus, nos sentimos mais confortáveis em executá-la e ela foi uma combinação melhor para nossa organização do que a Qdrant. Gostaríamos de ter tido mais tempo para testar a Vespa e a Weaviate, mas elas também podem ter sido selecionadas por adequação organizacional (a Vespa é baseada em Java) e arquitetura (a Weaviate é do tipo nó único, como a Qdrant).

Principais conclusões

  • Desafie os requisitos que lhe são dados e tente remover o viés da solução existente.

  • Pontuar as soluções candidatas e usá-las para informar a discussão sobre os requisitos essenciais, não como um ponto final

  • Avaliar quantitativamente as soluções, mas ao longo do caminho, tomar nota de como é trabalhar com a solução.

  • Escolha a solução que melhor se adapta à sua organização do ponto de vista da manutenção, do custo, da facilidade de utilização e do desempenho, e não apenas porque a solução tem o melhor desempenho.

Agradecimentos

Este trabalho de avaliação foi efectuado por Ben Kochie, Charles Njoroge, Amit Kumar e por mim. Agradecemos também a outros que contribuíram para este trabalho, incluindo Annie Yang, Konrad Reiche, Sabrina Kong e Andrew Johnson, pela investigação qualitativa da solução.

Notas do Editor

Queremos agradecer genuinamente à equipa de engenharia do Reddit - não só por escolherem o Milvus para as suas cargas de trabalho de pesquisa vetorial, mas também por dedicarem tempo a publicar uma avaliação tão detalhada e justa. É raro ver este nível de transparência na forma como equipas de engenharia reais comparam bases de dados, e o seu artigo será útil para qualquer pessoa da comunidade Milvus (e não só) que esteja a tentar perceber o crescente panorama das bases de dados vectoriais.

Como Chris mencionou no post, não existe uma única "melhor" base de dados vetorial. O que importa é se um sistema se adapta ao seu volume de trabalho, restrições e filosofia operacional. A comparação do Reddit reflecte bem essa realidade. O Milvus não está no topo de todas as categorias, e isso é completamente esperado, dadas as compensações entre diferentes modelos de dados e objectivos de desempenho.

Vale a pena esclarecer uma coisa: A avaliação do Reddit usou o Milvus 2.4, que era a versão estável na época. Alguns recursos - como LSH e várias otimizações de índice - ainda não existiam ou não estavam maduros na versão 2.4, portanto, algumas pontuações refletem naturalmente essa linha de base mais antiga. Desde então, lançámos o Milvus 2.5 e depois o Milvus 2.6, e é um sistema muito diferente em termos de desempenho, eficiência e flexibilidade. A resposta da comunidade tem sido forte e muitas equipas já fizeram a atualização.

Aqui está uma rápida olhada no que há de novo no Milvus 2.6:

  • Até 72% menos utilização de memória e consultas 4× mais rápidas com a quantização de 1 bit RaBitQ

  • 50% de redução de custos com armazenamento inteligente em camadas

  • Pesquisa de texto completo BM25 4× mais rápida em comparação com o Elasticsearch

  • Filtragem JSON 100 vezes mais rápida com o novo Path Index

  • Uma nova arquitetura de disco zero para uma pesquisa mais fresca a um custo mais baixo

  • Um fluxo de trabalho "data-in, data-out" mais simples para incorporar pipelines

  • Suporte para mais de 100 mil colecções para lidar com grandes ambientes multi-tenant

Se quiser ver a análise completa, aqui estão alguns bons acompanhamentos:

Tem dúvidas ou quer um mergulho profundo em qualquer recurso? Junte-se ao nosso canal Discord ou arquive problemas no GitHub. Também pode reservar uma sessão individual de 20 minutos para obter informações, orientação e respostas às suas perguntas através do 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

    Continue Lendo