Realizamos testes comparativos com Neo4j, FalkorDB e Memgraph em um grafo sintético derivado de 120.000 avaliações de produtos da Amazon (381 mil nós, 804 mil arestas). Executamos 12 modelos de consulta com 1.000 medições cada, testamos a ingestão em 6 tamanhos de lote, suportamos carga concorrente por 60 segundos com até 32 threads e medimos o consumo de memória, inicialização a frio, carga de trabalho mista e impacto nos índices.
O FalkorDB apresentou um desempenho superior ao Neo4j e ao Memgraph com 8 threads.
Resultados de benchmark de banco de dados de grafos
taxa de transferência simultânea
QPS (consultas por segundo) mede quantas consultas de leitura o banco de dados responde por segundo sob carga multithread contínua. Cada execução dura 60 segundos. Quanto maior, melhor.
Latência da consulta (p50)
p50 é a latência mediana: metade de todas as consultas terminam mais rápido do que esse valor. Quanto menor, melhor.
- Busca pontual: Busca um único nó por ID. As tabelas hash Redis do FalkorDB fazem buscas em memória O(1), aproximadamente 3 vezes mais rápidas.
- Percurso: Percorre um nó a partir de seus vizinhos (1 salto) ou vizinhos de vizinhos (2 saltos). O FalkorDB realiza percursos de 2 saltos 2,9 vezes mais rápido.
- Agregação: Contabilizar avaliações por marca e calcular a classificação média por estrelas.
- Filtrar + analisar: Filtre as avaliações por classificação por estrelas em todo o conjunto de dados.
taxa de transferência de ingestão
A taxa de transferência de ingestão mede quantas avaliações por segundo o banco de dados consegue gravar. Cada ponto no gráfico representa um tamanho de lote diferente: quantas avaliações são agrupadas em uma única consulta. Quanto maior, melhor.
Com um tamanho de lote de 1, o Memgraph lidera (1.427/s). À medida que o tamanho do lote aumenta, o FalkorDB escala acentuadamente e ultrapassa o Memgraph por volta do lote 500. O Neo4j atinge um platô em torno de 10.600/s, independentemente do tamanho do lote. Com um lote de 5.000, o FalkorDB alcança 22.784/s, 77 vezes o seu desempenho com um lote de 1.
Você pode ler mais sobre nossa metodologia de avaliação comparativa de bancos de dados de grafos .
Principais conclusões
O FalkorDB atinge 6.693 QPS com 8 threads, 6,7x Neo4j.
As estruturas de dados em memória e o loop de eventos do Redis permitem combinar consultas de baixa latência com alto paralelismo. Após 8 threads, a taxa de transferência se estabiliza porque o núcleo de thread única do Redis representa o limite máximo. O Neo4j atinge o pico com 16 threads (1.010 QPS) e depois cai com 32 (927 QPS), o que indica contenção de threads.
O FalkorDB inicia a frio em 1,1 ms, 82 vezes mais rápido que o Neo4j.
O Neo4j leva 90 ms para aceitar a primeira consulta após uma reinicialização. A primeira consulta de aquecimento leva 274 ms, e depois são necessárias cerca de 3 consultas para estabilizar em 34 ms. O FalkorDB fica pronto em 1,1 ms, com a primeira consulta em 0,4 ms. Em uma configuração de microsserviços ou serverless, onde os pods escalam verticalmente e horizontalmente, essa diferença é significativa.
Índices: diferença de 1.700x no Neo4j, ~1x no FalkorDB.
Sem índices, a consulta deep_feature_products do Neo4j levou 293 ms. Com índices, 0,17 ms. Isso representa uma diferença de 1.712 vezes. O Memgraph apresentou sensibilidade semelhante (160 a 898 vezes, dependendo da consulta). Os resultados do FalkorDB permaneceram praticamente os mesmos com ou sem índices, porque as tabelas hash do Redis já funcionam como índices implícitos.
Memória: 415 MB vs 2.668 MB para o mesmo gráfico
- Memgraph: 415 MB
- FalkorDB: 496 MB
- Neo4j: 2.668 MB (heap JMX utilizado)
A JVM do Neo4j pré-aloca 4 GB na inicialização, portanto, sua memória em nível de processo (VmRSS) é sempre de aproximadamente 5,2 GB, independentemente do uso real de dados. A métrica de heap JMX é a mais relevante. O pico de 2,7 GB é o valor a ser usado para o planejamento de capacidade.
Neo4j venceu a agregação mais pesada.
O FalkorDB apresentou a menor latência em 11 das 12 consultas. A exceção foi a consulta agg_feature_sentiment (agrupamento por sentimento com filtragem), na qual o otimizador de consultas do Neo4j gerou um plano de execução melhor: 131 ms contra 152 ms do FalkorDB.
Carga de trabalho mista (80% leitura, 20% gravação)
8 threads, 60 segundos, zero erros em todos os três bancos de dados:
- FalkorDB: 50.223 operações (837 QPS)
- Neo4j: 44.256 operações (738 QPS)
- Memgraph: 28.040 operações (467 QPS)
As operações de escrita não degradaram de forma perceptível o desempenho de leitura em nenhum deles.
Arquiteturas neste benchmark
Cada banco de dados possui sua própria interface de gerenciamento. Estas capturas de tela mostram o mesmo conjunto de dados (16.127 nós, 24.318 arestas) carregado nos três bancos de dados, executando a mesma consulta de travessia COMPARED_WITH.
FalkorDB
O FalkorDB é um módulo gráfico construído sobre o armazenamento de chave-valor em memória do Redis. As consultas são feitas em OpenCypher, mas internamente utilizam tabelas hash do Redis. É por isso que as buscas pontuais levam de 0,044 a 0,048 ms.
Os outros dois bancos de dados neste benchmark apresentaram resultados 2 a 3 vezes superiores nas mesmas consultas. A desvantagem é que o núcleo de thread única do Redis significa que a taxa de transferência simultânea deixa de escalar além de 8 threads.
Neo4j
O Neo4j roda na JVM. A compilação JIT significa que consultas repetidas ficam mais rápidas com o tempo (aquecimento: 274 ms -> 34 ms). As pausas do coletor de lixo afetam a latência de cauda, mas são compensadas pela remoção de outliers do intervalo interquartil (IQR). O otimizador de consultas lida bem com planos de agregação complexos, e é daí que vem a vantagem agg_feature_sentiment . O custo é a pré-alocação de 4 GB de memória heap e a sobrecarga do coletor de lixo.
Memgraph
O Memgraph é escrito em C++. Sem sobrecarga da JVM. 415 MB para o conjunto de dados completo, o menor dos três. Mais rápido em inserções individuais (1.427/s) graças à sobrecarga mínima por consulta. Mas fica atrás em taxa de transferência simultânea (pico de 684 QPS). Compatível com Bolt, portanto funciona com o driver Neo4j.
Metodologia de avaliação comparativa de banco de dados de grafos
Ambiente
- RunPod 8 vCPU (AMD EPYC x86_64), 32 GB de RAM, Ubuntu 24.04 LTS
- Instalação nativa, sem Docker. Todas as três bases de dados na mesma máquina, conexões localhost.
- Python 3.12.3. Sessões persistentes para testes de thread única, sessões por chamada a partir de um pool de conexões para testes multithread.
Dados
- 120.000 avaliações sintéticas geradas a partir de distribuições Zipf (marcas, características) e Poisson (entidades, relacionamentos), semente fixa = 42.
- 6 tipos de nós: Avaliação, Produto, Avaliador, Marca, Recurso, Categoria
- 8 tipos de arestas: SOBRE, ESCRITO POR, NA CATEGORIA, FEITO POR, TEM POSITIVO, TEM NEGATIVO, MENÇÕES, COMPARADO COM
Consultas
12 modelos Cypher em 5 categorias: pesquisa pontual (3), percurso de 1 salto (2), percurso de 2 saltos (2), agregação (3), filtro (1), varredura completa (1). Cada consulta parametrizada é executada com 10 valores de parâmetros diferentes, 100 vezes cada, para 1.000 medições por consulta por banco de dados.
Os parâmetros são amostrados de todo o espaço de IDs usando a seleção ponderada de Zipf, de forma que tanto itens populares quanto raros sejam testados.
Três exemplos:
Pesquisa de ponto : Recupera um único nó por ID indexado
Travessia em 2 etapas : Percorra a história da marca, passando por seus produtos, até chegar às avaliações.
Agregação : Varredura completa do grafo com junção multi-hop e computação
Medição
- Cronometragem:
time.perf_counter_ns(), 500 consultas de aquecimento, mínimo de 100 execuções por consulta - Estatísticas: 10.000 amostras bootstrap, IC de 95%, remoção de outliers no intervalo interquartil (fator de 3,0x). Os dados brutos e filtrados são apresentados.
- Memória: Neo4j via heap JMX usado (VmRSS não tem significado porque a JVM pré-aloca), FalkorDB via Redis
used_memory_rss, Memgraph via/proc/{pid}/statusVmRSS.
Equidade
- O tamanho do pool de conexões, a contagem de aquecimento, as consultas Cypher, os dados e a máquina são os mesmos em todos os três bancos de dados.
- Teste de concorrência: carga sustentada de 60 segundos com 1, 2, 4, 8, 16 e 32 threads e um pool_size fixo de 32. Composição das consultas: 40% de travessia de 1 salto, 30% de travessia de 2 saltos, 20% de agregação e 10% de travessia de 3 saltos.
Bancos de dados testados
Limitações
Uma única máquina, um único nó por banco de dados. Sem testes de desempenho distribuídos ou em cluster. Clustering do Neo4j Enterprise e replicação do Memgraph estão fora do escopo.
Dados sintéticos com distribuições derivadas de avaliações reais da Amazon. Podem não corresponder a padrões específicos de carga de trabalho de produção.
Não foram medidos: persistência/recuperação de disco, pesquisa de texto completo, algoritmos de grafos (PageRank, detecção de comunidades) e cargas de trabalho com grande volume de escrita (mais de 50% de escritas).
Drivers diferentes: Neo4j e Memgraph usaram o driver Python do Neo4j, enquanto o FalkorDB usou o seu próprio. A diferença de sobrecarga foi inferior a 0,5 ms em testes com um único thread.
Conclusão
O FalkorDB venceu 11 de 12 consultas, atingiu 6.693 QPS e iniciou a frio em 1,1 ms. Para cargas de trabalho com grande volume de leitura em grafos, é a opção mais rápida neste benchmark. O Memgraph é a opção mais eficiente em termos de memória (415 MB contra 2,7 GB). O Neo4j oferece o ecossistema mais abrangente: RBAC, clustering, monitoramento e um otimizador de consultas que lida com planos de agregação complexos melhor do que as outras duas alternativas.
A arquitetura determina o limite máximo. Clusters distribuídos, grafos com mais de 1 milhão de nós e cargas de trabalho com grande volume de escrita são os testes que podem alterar essas classificações.
Seja o primeiro a comentar
Seu endereço de e-mail não será publicado. Todos os campos são obrigatórios.