Bataille Triplestore Open Source
Il existe de nombreuses bases de données de graphes qui prennent en charge Resource Description Framework (RDF) : Virtuoso, GraphDB, Stardog, AnzoGraph et RDFox, pour n'en citer que quelques-uns. Mais si les exigences de votre triplestore inclut open source, comme c'est le cas pour notre projet LINCS financé par la FCI financé par Blazegraph et Jena Fuseki d'Apache sont deux de vos options les plus matures...
Cet article compare Blazegraph et Jena Fuseki, deux prétendants au LINCS base de données de graphes. Merci à Angus Addlesee d'avoir écrit un article qui a comparé Blazegraph aux triplestores commerciaux et a inspiré la méthodologie de test pour cet article.
Blazegraphe
Blazegraph, anciennement connu sous le nom de Bigdata, est un excellent triplestore qui s'adapte à des milliards de triples avec des milliers de cas d'utilisation éprouvés. En fait, c'était tellement bon qu'AWS a acheté la marque Blazegraph (https://trademark.trademarkia.com/blazegraph-86498414.html) il y a près de cinq ans et a embauché une partie de son personnel, y compris le PDG. Malheureusement, cela signifie que la majeure partie de l'expérience de développement de Blazegraph a été utilisée pour créer un produit concurrent : Amazon [Neptune](https://www.bobdc.com/blog/sparql-and-amazon-web-services/ .html). Bien que les versions officielles de Blazegraph aient ralenti, il prend toujours en charge SPARQL 1.1 et n'est en aucun cas obsolète.
Fuseki
Le Fuseki d'Apache, ainsi que l'ensemble du projet Jena et tous ses plugins, sont toujours activement développés en octobre 2020. Il prend en charge la mise à jour SPARQL 1.1 et obtient de nouvelles fonctionnalités et améliorations à chaque nouvelle version, qui a lieu environ tous les trimestres. Nous savons que Fuseki peut adapter le chargement de l'intégralité du vidage Wikidata. Mais à quoi ressemblent les performances des requêtes et peuvent-elles être comparées à Blazegraph ? Découvrons-le!
La mise en place
Essayer d'avoir une compétition équitable dans un match comme celui-ci est très difficile. Différents produits ont presque toujours des forces différentes et une analyse comparative sélective peut facilement fausser les résultats. Obtenir des résultats unilatéraux n'était pas l'intention ici, mais j'ai choisi un petit ensemble de tests, car une suite de tests exhaustive nécessiterait un livre et non un article. Mes tests impliquaient de charger un ensemble de données sportives olympiques avec ~1,8 million de triplets, puis d'exécuter des requêtes SPARQL en utilisant l'interface Web intégrée des deux triplestores.
L'instance Blazegraph est basée sur une version de septembre 2016 de la branche 2.2.0 selon le Dockerfile. Cette image a recherche en texte intégral activé ainsi qu'un geo indice.
J'ai utilisé ce fichier docker du projet LINCS pour créer une instance Fuseki basée sur la dernière version v3.16. Il s'agit d'une configuration TDB2 de base avec un index de texte intégral pour toutes les propriétés rdfs:label.
Les tests ont été exécutés sur un Core-i5 de la série 8 avec des SSD et beaucoup de RAM. Aucun triplestore n'a été "réchauffé" et les requêtes ont été exécutées dans le même ordre et le même nombre de fois dans le but de maintenir le terrain de jeu aussi égal que possible.
Les tests
Les requêtes SPARQL utilisaient ces préfixes :
PREFIX walls: <http://wallscope.co.uk/ontology/olympics/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
Les requêtes ont été exécutées deux fois et les deux résultats ont été enregistrés.
Chargement des données
Il est assez important pour la plupart des projets de savoir combien de temps il faudra pour charger les données dans le triplestore. Étant donné que notre ensemble de données est relativement petit (<2 millions de triplets), j'ai pu utiliser l'interface Web des deux triplestores pour charger le fichier TTL sans aucun problème.
Fuseki : 57s, 30.3s
Blazegraphe : 57s, 21.5s
La deuxième exécution était une mise à jour avec le même fichier TTL utilisé lors de la première exécution. Aucune modification réelle n'a été apportée au graphique.
Compter les triplets
La plus simple des requêtes pour voir combien de triplets se trouvent dans l'ensemble de données.
SELECT (COUNT(*) AS ?triples)
WHERE {
?s ?p ?o .
}
Fuseki: 0.8s, 0.5s
Blazegraph: 0.02s, 0.01s
Il semble que Blazegraph ait effectué une pré-agrégation ici lors du chargement des données.
Filtre Regex
SELECT DISTINCT ?name ?cityName ?seasonName
WHERE {
?instance walls:games ?games ;
walls:athlete ?athlete .
?games dbp:location ?city ;
walls:season ?season .
?city rdfs:label ?cityName .
?season rdfs:label ?seasonName .
?athlete rdfs:label ?name .
Filter (REGEX(lcase(?name),"louis.*"))
}
Fuseki: 7.7s, 5.0s
Blazegraph: 7.0s, 4.2s
Blazegraph était toujours plus rapide et plongeait plus loin avec cette requête typique.
Recherche plein texte
L'utilisation efficace de l'index de texte intégral nécessitait des requêtes légèrement différentes car Fuseki fonctionnait très lentement à moins que la recherche de texte intégral ne soit le premier filtre.
PREFIX text: <http://jena.apache.org/text#>
SELECT DISTINCT ?name ?cityName ?seasonName
WHERE {
?athlete text:query ('louis*') ;
rdfs:label ?name .
?instance walls:games ?games .
?games dbp:location ?city ;
walls:season ?season .
?city rdfs:label ?cityName .
?season rdfs:label ?seasonName .
}
PREFIX bds: <http://www.bigdata.com/rdf/search#>
SELECT DISTINCT ?name ?cityName ?seasonName
WHERE {
?instance walls:games ?games ;
walls:athlete ?athlete .
?games dbp:location ?city ;
walls:season ?season .
?city rdfs:label ?cityName .
?season rdfs:label ?seasonName .
?athlete rdfs:label ?name .
?name bds:search "'louis*'" .
}
Fuseki: 0.2s, 0.1s
Blazegraph: 0.3s, 0.1s
Déplacer le filtre de texte intégral vers le haut pour Blazegraph l'a également rendu plus rapide que Fuseki - 0,08 s pour la première exécution et 0,04 s pour la deuxième exécution.
Jointure complexe
PREFIX noc: <http://wallscope.co.uk/resource/olympics/NOC/>
SELECT ?genderName (COUNT(?athlete) AS ?count)
WHERE {
?instance walls:games ?games ;
walls:athlete ?athlete .
?games dbp:location ?city .
?athlete foaf:gender ?gender .
?gender rdfs:label ?genderName .
{
SELECT DISTINCT ?city
WHERE {
?instance walls:games ?games ;
walls:athlete ?athlete .
?athlete dbo:team ?team .
noc:SCG dbo:ground ?team .
?games dbp:location ?city .
}
}
}
GROUP BY ?genderName
Fuseki: DNF
Blazegraph: 7.0s, 6.0s
Fuseki n'a pas réussi à terminer cette requête avant le délai configuré de 10 minutes.
Requête fédérée
Cette requête joint un graphique sur Internet à partir de dbpedia.org.
SELECT ?sport ?sportName ?teamSize
WHERE {
{
SELECT DISTINCT ?sportName
WHERE {
?sport rdf:type dbo:Sport ;
rdfs:label ?sportName .
}
}
SERVICE <http://dbpedia.org/sparql>
{
?sport rdfs:label ?sportName ;
dbo:teamSize ?teamSize .
}
}
ORDER BY DESC (?teamSize)
Fuseki: 7.9s, 7.5s
Blazegraph: 0.5s, 0.4s
Sommaire
Tester | Fuseki | Blazegraphe |
---|---|---|
Chargement de données | 57s | 57s |
Compte triple | 0.8s | 0.02s |
Expression régulière | 7.7s | 7.0s |
Texte intégral | 0.2s | 0.1s |
Complexe | DNF | 7.0s |
Fédéré | 7.9s | 0.5s |
Je dois avouer que j'ai été quelque peu surpris par les résultats. Blazegraph a toujours mieux performé que Fuseki dans ce scénario. La requête complexe que Fuseki n'a tout simplement pas pu terminer pourrait être un problème d'indexation. Quoi qu'il en soit, Blazegraph a exécuté la même requête très bien dès la sortie de la boîte. Blazegraph a également battu Fuseki de plus d'un ordre de grandeur avec la requête fédérée.
Une explication possible de ces résultats unilatéraux est que les index de Blazegraph sont mieux configurés pour cet ensemble de données et je dois faire plus d'efforts pour optimiser les index de Fuseki. N'hésitez pas à regarder le config.ttl que j'ai utilisé pour configurer Fuseki et faites le moi savoir dans le commentaires si j'ai raté une optimisation évidente ou si j'ai mal configuré quelque chose.
Suivi de configuration Fuseki
Bien que j'aie essayé de configurer Fuseki avec l'index de texte intégral le plus simple possible, je craignais qu'une mauvaise configuration n'ait pu être la cause des performances décevantes comparatives. Pour exclure cette possibilité, et par souci d'exhaustivité, j'ai exécuté les tests par rapport aux bases de données Fuseki par défaut créées à partir du portail d'administration sans aucune personnalisation.
Magasin en mémoire | Magasin TDB | Magasin TDB2 |
---|---|---|
Chargement des données : 25 s, 27 s | Chargement de données : 43 s, 30 s | Chargement des données : 54s, 28s |
Comptage : 2,8 s, 1,6 s | Comptage : 0,9 s, 0,7 s | Comptage : 0,7 s, 0,6 s |
Expression régulière : 2,8 s, 2,2 s | Expression régulière : 4,5 s, 3,3 s | Expression régulière : 7,8 s, 5,7 s |
Texte intégral : non activé | Texte intégral : non activé | Texte intégral : non activé |
Complexe : DNF | Complexe : DNF | Complexe : DNF |
Fédéré : 8,7 s, 7,4 s | Fédéré : 8,5 s, 8,3 s | Fédéré : 7,7 s, 7,7 s |
Les résultats étaient plus ou moins alignés sur les chiffres de performance d'origine. Il semble donc que vanilla Fuseki soit juste considérablement plus lent que Blazegraph pour cet ensemble de données et ces requêtes.