o problema
Modelos de embedding transformaram texto, imagem, áudio e estrutura química em vetores, e a operação central de recomendação, busca e deduplicação virou “ache os k vetores mais próximos deste”. A escala descrita pelos autores é de centenas de bilhões de vetores, com crescimento diário na casa da centena de milhões e milhões de consultas por segundo. Banco relacional, NoSQL e NewSQL não foram construídos para isso. Biblioteca de busca vetorial resolve o algoritmo e para por aí: não tem execução distribuída, atualização online nem recuperação de falha.
A Zilliz já tinha um banco vetorial, o Milvus, aberto em 2019. Depois de três anos e mais de 1.200 usuários industriais, a conclusão foi que o Milvus havia copiado as regras erradas — as do banco relacional. Três desencontros. Transação complexa não serve quando o modelo codifica a entidade inteira num vetor: ACID por linha basta e join não existe. Consistência não é binária, e boa parte dos clientes quer um meio-termo configurável entre forte e eventual. E o hardware é caro demais — GPU, RAM grande — para escalar o sistema em bloco: no Milvus havia vários nós de leitura e um só de escrita, então inserção e construção de índice disputavam recurso, o índice demorava a ficar pronto e a busca caía para varredura bruta.
a ideia
O Manu troca complexidade transacional por desacoplamento. Como não há transação de várias linhas para proteger, o sistema pode ser reescrito como um grupo de micro-serviços que publicam e assinam log. WAL e binlog deixam de ser detalhe interno e viram serviço: quem escreve publica, e todo componente read-only — busca, indexação, arquivamento — é apenas mais um assinante que se mantém atualizado por conta própria.
O truque é que a mesma primitiva paga duas contas. Cada entrada do log recebe um timestamp global, e mensagens especiais chamadas time-tick são injetadas periodicamente em cada canal, como as watermarks do Flink, sinalizando até onde o tempo de evento já avançou. Esse relógio dá MVCC, dá ordem determinística para as mensagens de coordenação entre componentes e dá a consistência ajustável, tudo do mesmo mecanismo.
como funciona
São quatro camadas. O access layer é feito de proxies sem estado, que validam a requisição cedo, roteiam e agregam o resultado parcial. O coordinator layer tem quatro coordenadores separados — root, data, query e index — cada um com uma instância principal e backups quentes. O worker layer tem query nodes, index nodes e data nodes, todos sem estado, trabalhando sobre cópias read-only. O storage layer usa etcd para metadado e S3, MinIO ou sistema de arquivos local para o resto.
Na escrita, os loggers ficam num anel de hashing consistente; cada shard corresponde a um bucket do anel e a um canal de WAL. O logger consulta um TSO com relógio lógico híbrido — componente físico mais componente lógico — para atribuir o LSN, decide o segmento de destino e grava. Data nodes assinam o WAL e convertem o log baseado em linha em binlog baseado em coluna, o que permite ao index node ler só o campo de que precisa.
Segmento é a unidade de colocação. Ele nasce growing e vira sealed ao atingir 512MB ou depois de um período sem inserção, e aí um index node constrói o índice definitivo. Enquanto está growing, o segmento é dividido em fatias de 10.000 vetores; quando a fatia enche, ganha um índice temporário leve, que os autores mediram acelerando em até 10 vezes a busca no segmento em crescimento. Deleção é bitmap, com reconstrução do índice quando o acúmulo justifica.
A consistência delta fecha o ciclo: com tolerância τ, se a diferença entre o instante da consulta e o último time-tick consumido não couber em τ, o query node espera o próximo tick antes de executar. A busca em si é reduce em duas fases — top-k por segmento, top-k por nó, agregação global no proxy.
o que isso custou
O modelo de dados é pobre por decisão: coleções não se relacionam, não há join nem agregação, e os campos de atributo servem só para filtro. Consistência tem preço em latência, e o paper mostra isso: quanto menor o grace time, mais a consulta espera, e intervalo de time-tick mais curto reduz a espera às custas de mais mensagens de controle. O Manu também carrega todos os dados nos query nodes, ao contrário de um Snowflake que busca sob demanda, porque o acesso a vetor tem localidade ruim. E a redistribuição de segmentos não é atômica — um segmento pode estar em dois nós ao mesmo tempo, e a correção vem do proxy deduplicando resultado.
Os autores admitem que configurar índice é difícil até para especialista, e por isso embutiram busca automática de parâmetros com BOHB, ainda em melhoria. A avaliação também é modesta: comparação com outros sistemas só num subconjunto dos experimentos, por limite de tempo e custo, e datasets de 10 milhões de vetores porque o Elasticsearch levava tempo demais para indexar mais que isso.
onde isso aparece hoje
O artefato do paper aponta para o Milvus 2.0: o Manu é a reescrita do Milvus, não um sistema paralelo. O WAL roda sobre fila de mensagens de nuvem como Kafka ou Pulsar, e o desenho de armazenamento em objeto com computação sem estado é o mesmo do Snowflake, aplicado a outro tipo de dado.
Do lado da busca, o Manu não inventa índice — ele empacota os que já existiam: quantização como product quantization, índice invertido e grafo de proximidade como o HNSW, com implementações na linha do Faiss. A solução de SSD venceu a track 2 do desafio de busca aproximada em escala de bilhões do NeurIPS de 2021, melhorando o recall do baseline em até 60% com a mesma vazão. Os domínios de uso listados no paper — recomendação, multimídia, linguagem, segurança, medicina — se apoiam em embeddings de modelos como word2vec e BERT, e o padrão de recuperação que alimenta llm com documentos, RAG, depende exatamente desse tipo de serviço. O survey de 2023 sobre técnicas e sistemas de banco vetorial trata essa geração como estado da arte.