Les bases de données orientées graphe peuvent vous aider à dégager des insights en modélisant vos entités de données et leurs relations. JanusGraph est une base de données orientée graphe qui permet de travailler sur de grands volumes de données. Ce tutoriel explique comment exécuter JanusGraph sur Google Cloud avec Google Kubernetes Engine comme plate-forme d'orchestration et Bigtable comme backend de stockage. Il est destiné aux architectes système, aux administrateurs de bases de données et aux professionnels DevOps qui souhaitent exécuter la base de données orientée graphe JanusGraph sur Google Cloud à l'aide d'une base de données gérée comme backend de stockage. Il part du principe que vous connaissez bien Google Kubernetes Engine (GKE), les pods Kubernetes, les charts Helm, Bigtable et Elasticsearch. La connaissance du framework de calcul de graphe Apache TinkerPop et de la machine et du langage de balayage de graphe Gremlin n'est pas requise, mais elle est nécessaire pour utiliser Janusgraph au-delà des exemples fournis dans ce tutoriel.
Présentation
Dans la terminologie des graphes, les entités sont appelées nœuds ou sommets, et les relations sont appelées arêtes. Dans JanusGraph, les sommets et les arêtes peuvent posséder des données associées supplémentaires qui sont disponibles via des propriétés.
L'illustration précédente est un exemple de graphe de propriétés.
Les bases de données orientées graphe vous aident à modéliser divers domaines et activités :
- Réseaux sociaux
- Transactions financières (pour l'analyse de fraude)
- Réseaux de systèmes physiques ou virtuels
La création de bases de données orientées graphe conduit parfois à créer des millions, voire des milliards de sommets et d'arêtes. Lorsque vous utilisez JanusGraph avec Bigtable comme couche de stockage sous-jacente, vous pouvez à la fois exécuter des requêtes rapides (appelées balayages de graphe) et faire évoluer votre couche de stockage indépendamment en fonction de la taille et du débit dont vous avez besoin. JanusGraph utilise également un backend d'indexation connectable pour fournir une indexation en texte intégral des propriétés des sommets et des arêtes. Dans ce tutoriel, vous allez déployer une infrastructure JanusGraph évolutive sur GKE. Vous utiliserez Elasticsearch comme backend d'indexation s'exécutant dans les pods d'un StatefulSet, et vous utiliserez Bigtable comme backend de stockage. Lorsque vous aurez terminé, vous pourrez parcourir les relations existant dans vos données de graphe. Le schéma suivant montre comment ces éléments s'intègrent les uns aux autres.
Le schéma précédent montre le déploiement de JanusGraph sur GKE avec Elasticsearch et Bigtable.
Données JanusGraph dans Bigtable
Les données de graphe sont stockées par JanusGraph sous la forme d'une liste de contiguïté. Chaque ligne représente un sommet, tous les sommets adjacents (arêtes) et des métadonnées de propriété concernant les sommets et les arêtes. La clé de ligne est l'identifiant unique du sommet. Chaque relation entre le sommet et un autre sommet, ainsi que toutes les propriétés qui définissent davantage la relation, sont stockées sous forme d'arête ou de colonne de propriété d'arête. Le qualificatif de colonne et la valeur de colonne stockent tous deux les données qui définissent l'arête, conformément aux bonnes pratiques de Bigtable. Chaque propriété de sommet est stockée dans une colonne distincte, en utilisant à nouveau le qualificatif de colonne et la valeur de colonne pour définir la propriété.
Le schéma suivant illustre cette structure de stockage.
Le schéma montre la structure de stockage logique d'un petit fragment de graphe avec des détails logiques pour deux lignes de sommet. Dans le schéma, les deux exemples de lignes représentent deux sommets. Le premier sommet est étiqueté avec une propriété de sommet unique et est lié à deux autres sommets par deux arêtes distinctes. Le second sommet comporte des colonnes contenant deux propriétés et une arête.
L'illustration suivante du modèle de données logique de l'arête de sommet fournit des informations détaillées sur les qualificatifs et les valeurs d'une colonne d'arête ou de propriété d'arête.
Pour chaque sommet adjacent, une colonne stocke les métadonnées de cette arête. Le qualificatif de colonne contient des métadonnées sur la relation de l'arête et sur sa direction, ainsi qu'un pointeur vers le sommet adjacent. La valeur de la colonne contient l'étiquette de l'arête et toutes les propriétés d'arête supplémentaires. Étant donné que les balayages peuvent être suivis dans les deux sens, les arêtes sont stockées deux fois : une fois pour chaque extrémité de la relation d'arête. Le stockage d'arête bidirectionnel augmente considérablement les performances de balayage, mais présente certains compromis en raison de la redondance de l'espace de stockage supplémentaire et des mutations d'arête non atomiques.
Le schéma suivant est le modèle de données logique d'une colonne de propriété de sommet.
L'illustration précédente fournit des détails sur les qualificatifs et les valeurs d'une colonne d'arête.
Chaque propriété de sommet est stockée dans une colonne distincte. Le qualificatif de colonne est un identifiant unique pour la clé de propriété. La valeur de la colonne contient à la fois un identifiant de la propriété et la valeur de la propriété.
JanusGraph s'appuie également sur l'ordre lexicographique Bigtable des lignes et des qualificatifs de colonnes pour améliorer les performances des requêtes.
Objectifs
- Créer une instance Bigtable
- Créez un cluster GKE.
- Installer Helm
- Utiliser un graphique Helm pour déployer Janusgraph et Elasticsearch
- Utiliser la console Gremlin et se connecter à JanusGraph
- Charger, puis interroger des exemples de données
Coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
- Google Kubernetes Engine (GKE)
- Compute Engine VMs are provisioned by GKE
- Bigtable
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.
Prérequis
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Bigtable, Compute Engine, and GKE APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Bigtable, Compute Engine, and GKE APIs.
Préparer votre environnement
Dans ce tutoriel, vous utilisez Cloud Shell pour saisir des commandes. Cloud Shell vous donne accès à la ligne de commande dans la console Google Cloud. En outre, il intègre Google Cloud CLI ainsi que d'autres outils dont vous pourrez avoir besoin pour le développement dans Google Cloud. Cloud Shell apparaît sous la forme d'une fenêtre en bas de la console Google Cloud. L'initialisation peut prendre quelques minutes, mais la fenêtre apparaît immédiatement.
-
In the Google Cloud console, activate Cloud Shell.
Dans Cloud Shell, définissez les variables d'environnement pour la zone Compute Engine dans laquelle vous allez créer votre cluster Bigtable et votre cluster GKE, ainsi que le nom, le type de nœud et la version de votre cluster GKE :
export PROJECT_ID=PROJECT_ID export GCP_ZONE=REGION export GKE_CLUSTER_NAME=GKE_CLUSTER_NAME export GKE_NODE_TYPE=n1-standard-4 export GKE_VERSION=1.20
Remplacez les éléments suivants :
PROJECT_ID
par votre identifiant de projet.REGION
par la zone dans laquelle votre cluster Bigtable et votre cluster GKE seront créés.GKE_CLUSTER_NAME
par le nom de votre cluster GKE.
La commande doit ressembler à l'exemple suivant :
export PROJECT_ID=bt-janusgraph-project-id export GCP_ZONE=us-central1-f export GKE_CLUSTER_NAME=janusgraph-gke export GKE_NODE_TYPE=n1-standard-4 export GKE_VERSION=1.20
Créez un cluster GKE dans lequel JanusGraph sera déployé :
gcloud container clusters create ${GKE_CLUSTER_NAME} \ --zone=${GCP_ZONE} \ --cluster-version=${GKE_VERSION} \ --machine-type ${GKE_NODE_TYPE} \ --scopes "https://www.googleapis.com/auth/cloud-platform"
Créer une instance Bigtable
Ce tutoriel utilise Bigtable comme backend de stockage pour JanusGraph, car Cloud Bigtable peut évoluer rapidement pour répondre à vos besoins. Nous utilisons ici un cluster à un seul nœud, ce qui est à la fois économique et suffisant pour ce tutoriel. Vous pouvez démarrer vos projets avec un cluster plus petit, puis passer à un cluster plus grand lorsque vous êtes prêt à utiliser les données de production. Dans la documentation de Bigtable, vous trouverez des informations détaillées sur les performances et le scaling qui vous aideront à choisir une taille de cluster adaptée à votre propre travail.
Dans Cloud Shell, définissez la variable d'environnement correspondant à votre identifiant d'instance Bigtable :
export BIGTABLE_INSTANCE_ID=BIGTABLE_INSTANCE_ID
Remplacez
BIGTABLE_INSTANCE_ID
par l'identifiant de votre instance Bigtable.Créez l'instance Bigtable :
gcloud bigtable instances create ${BIGTABLE_INSTANCE_ID} \ --cluster-config=id=${BIGTABLE_INSTANCE_ID}-${GCP_ZONE},zone=${GCP_ZONE},nodes=1 \ --display-name=${BIGTABLE_INSTANCE_ID}-${GCP_ZONE}
Installer et configurer Helm
Helm sert à déployer des applications sur votre cluster Kubernetes. Dans ce tutoriel, vous allez utiliser Helm pour déployer les services JanusGraph et Elasticsearch sur votre cluster GKE.
Dans Cloud Shell, installez Helm :
curl -fsSL -o get_helm.sh \ https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 chmod 700 get_helm.sh DESIRED_VERSION=v3.5.0 ./get_helm.sh
Ajoutez le dépôt de chart
elastic
afin que la dépendance de chart Elasticsearch puisse être trouvée lors du déploiement de chart JanusGraph :helm repo add elastic https://helm.elastic.co
Ce dépôt de chart est hébergé par Elastic, les créateurs d'Elasticsearch.
Utiliser Helm pour installer JanusGraph et Elasticsearch
Dans cette section, vous utilisez un graphique Helm pour déployer JanusGraph et Elasticsearch sur votre cluster Kubernetes.
Le chart Helm est extrait de GitHub. Le déploiement inclus dans le dépôt de chart Helm déploie un ensemble de trois pods JanusGraph derrière un objet Service qui démarre un équilibreur de charge d'application interne. Lorsque les pods sont en cours d'exécution, les vérifications de démarrage et d'activité exécutent des requêtes HTTP afin d'effectuer des vérifications d'état sur le serveur JanusGraph sur chaque pod. En outre, le chart inclut un chart de dépendance fourni par Elastic qui déploie trois pods Elasticsearch dans un StatefulSet.
Dans Cloud Shell, définissez des variables d'environnement pour les noms Helm et JanusGraph :
export HELM_REPO=bigtable-janusgraph-helm export JANUSGRAPH_VERSION=0.5.3 export HELM_CHART_RELEASE_VERSION=1 export HELM_CHART_RELEASE_TAG=${JANUSGRAPH_VERSION}-${HELM_CHART_RELEASE_VERSION} export HELM_CHART_RELEASE_TAG_HASH=f8b271a4854d4a553dd5e9ba014d077fb098d9ab export HELM_CHART_NAME=janusgraph-bigtable
Extrayez le chart Helm de GitHub :
git clone https://github.com/GoogleCloudPlatform/${HELM_REPO} \ --branch ${HELM_CHART_RELEASE_TAG}
Accédez au répertoire du chart Helm :
cd ${HELM_REPO}
Pour des raisons de sécurité, vérifiez la sortie à l'aide du hachage de commit :
HEAD_COMMIT_HASH=$(git rev-parse --verify HEAD) if [ _${HEAD_COMMIT_HASH} == _${HELM_CHART_RELEASE_TAG_HASH} ] then echo "Commit hash verified" fi
Si la sortie ne ressemble pas à ce qui suit, ne continuez pas, car l'intégrité du tag cloné n'a pas été vérifiée.
Commit hash verified
Mettez à jour les dépendances de chart :
helm dep update
Accédez au répertoire parent :
cd ..
Définissez les variables d'environnement pour les noms des entités Helm et JanusGraph :
export HELM_RELEASE_NAME=janusgraph-bigtable-elastic export ELASTICSEARCH_CLUSTER_NAME=${HELM_RELEASE_NAME}-elasticsearch export BIGTABLE_JANUSGRAPH_TABLE=janusgraph-table
Créez un fichier
values.yaml
, qui fournit à Helm les propriétés de configuration à utiliser pour le déploiement du chart JanusGraph :cat > values.yaml << EOF image: repository: docker.io/janusgraph/janusgraph tag: 0.5.3 pullPolicy: IfNotPresent replicaCount: 3 service: type: LoadBalancer port: 8182 serviceAnnotations: networking.gke.io/load-balancer-type: "Internal" elasticsearch: deploy: true clusterName: ${ELASTICSEARCH_CLUSTER_NAME} properties: storage.backend: hbase storage.directory: null storage.hbase.ext.google.bigtable.instance.id: ${BIGTABLE_INSTANCE_ID} storage.hbase.ext.google.bigtable.project.id: ${PROJECT_ID} storage.hbase.ext.hbase.client.connection.impl: com.google.cloud.bigtable.hbase2_x.BigtableConnection storage.hbase.short-cf-names: true storage.hbase.table: ${BIGTABLE_JANUSGRAPH_TABLE} index.search.backend: elasticsearch index.search.hostname: ${ELASTICSEARCH_CLUSTER_NAME}-master index.search.directory: null index.search.elasticsearch.health-request-timeout: 90s cache.db-cache: true cache.db-cache-clean-wait: 20 cache.db-cache-time: 180000 cache.db-cache-size: 0.5 cluster.max-partitions: 1024 graph.replace-instance-if-exists: true persistence: enabled: false debugLevel: INFO EOF
Déployez le chart Helm de JanusGraph à l'aide du fichier
values.yaml
que vous avez créé :helm upgrade --install \ --wait \ --timeout 600s \ ${HELM_RELEASE_NAME} \ ./${HELM_REPO} \ -f values.yaml
Le processus d'installation attend que toutes les ressources soient prêtes avant de se terminer. Ce processus peut prendre plusieurs minutes.
Vérifier votre déploiement JanusGraph
Une fois l'installation de Helm terminée, une section NOTES
s'affiche. Elle décrit les premiers pas de l'utilisateur dans l'environnement. Vous pouvez suivre les étapes décrites dans la section NOTES
pour vérifier que votre environnement JanusGraph fonctionne correctement.
Dans Cloud Shell, vérifiez que les composants de chart Helm sont déployés sur GKE :
Vérifiez le déploiement de JanusGraph :
kubectl get deployments
Si le déploiement a réussi, la sortie est la suivante :
NAME READY UP-TO-DATE AVAILABLE AGE janusgraph-bigtable-elastic 3/3 3 3 3m28s
Vérifiez le StatefulSet Elasticsearch :
kubectl get statefulsets
Si tout fonctionne, la sortie est la suivante :
NAME READY AGE janusgraph-bigtable-elastic-elasticsearch-master 3/3 4m13s
Définissez une variable d'environnement sur le nom d'un pod Kubernetes qui exécute le serveur JanusGraph Gremlin. L'étiquette
app
du pod qui exécute le serveur Gremlin est dérivée du nom du chart Helm défini dans le fichierChart.yaml
.export APP_LABEL_FROM_CHART_NAME=${HELM_CHART_NAME} export POD_NAME=$(kubectl get pods \ --namespace default \ -l "app=${APP_LABEL_FROM_CHART_NAME}, \ release=${HELM_RELEASE_NAME}" \ -o jsonpath="{.items[0].metadata.name}")
Connectez-vous au pod et exécutez la console Gremlin, une interface système REPL (read-eval-print-loop). Le nom du conteneur est également dérivé du nom du chart Helm dans
Chart.yaml
.export GREMLIN_CONTAINER=${HELM_CHART_NAME} kubectl exec \ -c ${GREMLIN_CONTAINER} \ -it $POD_NAME \ -- /opt/janusgraph/bin/gremlin.sh
Dans la console Gremlin, connectez-vous au serveur Apache TinkerPop :
Démarrez la session :
:remote connect tinkerpop.server conf/remote.yaml session
La sortie ressemble à ceci :
==>Configured localhost/127.0.0.1:8182-[b08972f2-a2aa-4312-8018-bcd11bc9812c]
Connectez-vous au serveur :
:remote console
La sortie ressemble à ceci :
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182]-[b08972f2-a2aa-4312-8018-bcd11bc9812c] - type ':remote console' to return to local mode>
Dans la console Gremlin, vérifiez que le serveur Gremlin s'exécute correctement en inspectant la variable
graph
qui représente l'instance de graphe :graph
Le résultat indique que le serveur JanusGraph s'exécute avec une base de données compatible HBase, dans ce cas Bigtable, en tant que backend de stockage.
==>standardjanusgraph[hbase:[127.0.0.1]]
Dans Gremlin, créez deux sommets.
v1 = graph.addVertex(label, 'hello') v2 = graph.addVertex(label, 'world')
Si la sortie de la console ressemble à ce qui suit, cela indique que les deux sommets ont été ajoutés :
==>v[4344] ==>v[4152]
Créez une arête reliant les deux sommets :
v1.addEdge('followedBy', v2)
Si la sortie de la console ressemble à ce qui suit, cela signifie que l'arête entre les deux sommets a été ajoutée :
==>e[17j-3co-4fmd-oe054][4344-followedBy->4152]
Effectuez le commit de la transaction :
graph.tx().commit()
Si la sortie de la console est
null
, cela signifie que le commit des opérations a été effectué :==>null
Le diagramme suivant illustre le graphe créé par les commandes.
Le sommet étiqueté
hello
est relié par une arête dirigée étiquetéefollowedBy
au sommet étiquetéworld
.Envoyez une requête Gremlin pour voir quelle étiquette porte le sommet qui suit l'arête étiquetée
followedBy
en partant du sommet étiquetéhello
:g.V().has(label, 'hello').out('followedBy').label()
La syntaxe de la requête est expliquée dans la section suivante. Pour l'instant, vous voyez apparaître le mot
world
comme sortie de la requête :==>world
Charger et interroger un exemple d'ensemble de données
Maintenant que vous avez déployé JanusGraph et que vous pouvez vous y connecter au moyen de Gremlin, vous pouvez commencer à charger et interroger vos propres données. Pour voir à quoi ressemble ce processus, chargez l'exemple d'ensemble de données fourni avec JanusGraph : Graph of the Gods (graphe des dieux), qui décrit les divinités mythologiques du panthéon romain et leurs propriétés d'emplacement.
Dans Gremlin, chargez le graphe que vous avez créé précédemment :
GraphOfTheGodsFactory.load(graph)
Voici le résultat :
==>null
Émettez une requête de balayage de graphe qui trouve tous les frères de Jupiter :
g.V().has('name', 'jupiter').out('brother').values('name')
Le tableau suivant décrit les étapes du balayage de la requête.
Étape du balayage Explication g.V()
Commencer avec la collection de sommets. has('name', 'jupiter')
Identifier un sommet dont la propriété name
possède la valeurjupiter
.out('brother')
Ensuite, suivre toutes les arêtes portant le libellé brother
.values('name')
Récupérer la propriété name
de chaque sommet auquel ces arêtes conduisent.==>neptune ==>pluto
Pour vous familiariser avec les requêtes de balayage de graphe que vous pouvez réaliser sur cet ensemble de données "Graph of the Gods", essayez d'autres exemples de requêtes issues de la documentation JanusGraph.
Vérifier que les données sont stockées dans Bigtable
Maintenant que vous avez créé des exemples de données dans votre cluster JanusGraph, vous pouvez vérifier que Bigtable a été utilisé comme backend de stockage.
Fermez la console Gremlin :
:q
Dans Cloud Shell, vérifiez que les données ont été conservées dans la table
janusgraph
de Bigtable :cbt -project=${PROJECT_ID} \ -instance=${BIGTABLE_INSTANCE_ID} \ count ${BIGTABLE_JANUSGRAPH_TABLE}
Le résultat renvoyé ressemble à ceci :
2021/03/02 02:32:19 -creds flag unset, will use gcloud credential 101
La valeur
101
dans la sortie représente le nombre de lignes dansjanusgraph table
et peut être différente pour vous.
Vérifier la création de l'index de recherche dans Elasticsearch
Dans Cloud Shell, définissez des variables pour l'index et le nom du pod Elasticsearch :
export ELASTICSEARCH_POD_ORDINAL=0 export ELASTICSEARCH_POD_NAME_ROOT=${ELASTICSEARCH_CLUSTER_NAME}-master export ELASTICSEARCH_POD=${ELASTICSEARCH_POD_NAME_ROOT}-0
Les noms des pods Elasticsearch sont définis par les dépendances Elasticsearch Helm. Les noms des pods sont constitués du nom du cluster tel qu'il est fourni dans le fichier
values.yaml
que vous avez créé, du motmaster
et d'un numéro ordinal indexé par zéro, séparés par un trait d'union. Pour cette étape, vous choisissez le premier pod, représenté par zéro (0).Utilisez l'API REST Elasticsearch Aliases pour inspecter les index :
kubectl exec \ -c elasticsearch \ -it ${ELASTICSEARCH_POD} \ -- \ curl -XGET "127.0.0.1:9200/_aliases?pretty=true";
La sortie montre deux index,
janusgraph_vertices
etjanusgraph_edges
, qui ont été créés par JanusGraph pour fournir des recherches efficaces à l'aide des propriétés de sommet et d'arête :{ "janusgraph_vertices" : { "aliases" : { "janusgraph" : { } } }, "janusgraph_edges" : { "aliases" : { "janusgraph" : { } } } }
Interrogez les valeurs de l'un des index à l'aide de l'API REST Search Elasticsearch :
kubectl exec \ -c elasticsearch \ -it ${ELASTICSEARCH_POD} \ -- \ curl -XGET "127.0.0.1:9200/janusgraph_edges/_search?pretty=true&q=*";
Les résultats de recherche montrent que les index créés par JanusGraph contiennent des entrées. Le résultat renvoyé est semblable aux résultats tronqués suivants, qui montrent l'existence d'entrées dans l'index
janusgraph_edges
.{ "took" : 94, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 6, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "janusgraph_edges", "_type" : "_doc", "_id" : "6bvp-5ovc-b2t-2yko", "_score" : 1.0, "_source" : { "reason" : "loves waves" } }, { …
Supprimer le projet
Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez chaque ressource individuellement.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Étape suivante
- Apprenez-en plus sur JanusGraph et les bases de données orientées graphe.
- Découvrez le framework de calcul de graphe Apache TinkerPop et explorez le langage de balayage de graphe Gremlin.
- Découvrez comment JanusGraph stocke les données dans Bigtable.
- Approfondissez les cas d'utilisation de graphes en déployant un exemple d'application JanusGraph.