Mise en cache des résultats de requête dans Amazon Neptune Gremlin - Amazon Neptune

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Mise en cache des résultats de requête dans Amazon Neptune Gremlin

À partir de la version 1.0.5.1 du moteur, Amazon Neptune prend en charge un cache de résultats pour les requêtes Gremlin.

Vous pouvez activer ce cache, puis utiliser un indicateur de requête pour mettre en cache les résultats d'une requête Gremlin en lecture seule.

Toute nouvelle exécution de cette requête récupérera ainsi les résultats mis en cache avec une faible latence et sans frais d'E/S, tant qu'ils sont encore dans le cache. Ce comportement s'applique pour les requêtes soumises à la fois sur un point de terminaison HTTP et à l'aide de Websockets, sous forme de bytecode ou de chaîne.

Note

Les requêtes envoyées au point de terminaison de profil ne sont pas mises en cache même lorsque le cache de requêtes est activé.

Vous pouvez contrôler le comportement du cache des résultats de requête Neptune de plusieurs manières. Par exemple :

  • Vous pouvez obtenir les résultats mis en cache paginés, par blocs.

  • Vous pouvez spécifier le time-to-live (TTL) pour les requêtes spécifiées.

  • Vous pouvez vider le cache pour certaines requêtes.

  • Vous pouvez vider tout le cache.

  • Vous pouvez configurer le cache afin d'être averti si les résultats dépassent sa taille.

Le cache est maintenu selon une politique least-recently-used (LRU), ce qui signifie qu'une fois que l'espace alloué au cache est plein, les least-recently-used résultats sont supprimés pour faire de la place lorsque de nouveaux résultats sont mis en cache.

Important

Le cache des résultats de requête n'est pas disponible sur les types d'instance t3.medium et t4.medium.

Activation du cache des résultats de requête dans Neptune

Pour activer le cache des résultats de requête dans Neptune, utilisez la console afin de définir le paramètre de l'instance de base de données neptune_result_cache sur 1 (activé).

Une fois le cache des résultats activé, Neptune réserve une partie de la mémoire actuelle à la mise en cache des résultats de requête. Plus le type d'instance que vous utilisez est grand et plus la quantité de mémoire disponible est importante, plus Neptune réserve de mémoire au cache.

Si la mémoire cache des résultats est pleine, Neptune supprime automatiquement least-recently-used (LRU) les résultats mis en cache pour faire place à de nouveaux résultats.

Vous pouvez vérifier le statut actuel du cache de résultats à l'aide de la commande Statut d’une instance.

Utilisation d'indicateurs pour mettre en cache les résultats de requête

Une fois le cache des résultats de requête activé, vous pouvez utiliser des indicateurs de requête pour contrôler la mise en cache des requêtes. Tous les exemples ci-dessous s'appliquent à la même traversée de requêtes, à savoir :

g.V().has('genre','drama').in('likes')

Utiliser enableResultCache

Lorsque le cache des résultats de requête est activé, vous pouvez mettre en cache les résultats d'une requête Gremlin à l'aide de l'indicateur de requête enableResultCache, comme suit :

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

Neptune vous renvoie ensuite les résultats de la requête et les met également en cache. Plus tard, vous pourrez accéder aux résultats mis en cache en émettant à nouveau exactement la même requête :

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

La clé de cache qui identifie les résultats mis en cache est la chaîne de requête elle-même, à savoir :

g.V().has('genre','drama').in('likes')

Utiliser enableResultCacheWithTTL

Vous pouvez spécifier la durée pendant laquelle les résultats de la requête doivent être mis en cache à l'aide de l'indicateur de requête enableResultCacheWithTTL. Par exemple, la requête suivante indique que les résultats de la requête doivent expirer au bout de 120 secondes :

g.with('Neptune#enableResultCacheWithTTL', 120) .V().has('genre','drama').in('likes')

Là aussi, la clé de cache qui identifie les résultats mis en cache est la chaîne de requête de base :

g.V().has('genre','drama').in('likes')

Et là aussi, vous pouvez accéder aux résultats mis en cache à l'aide de cette chaîne de requête avec l'indicateur de requête enableResultCache :

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

Si 120 secondes ou plus se sont écoulées depuis la mise en cache des résultats, cette requête renverra de nouveaux résultats et les mettra en cache, sans aucun time-to-live.

Vous pouvez également accéder aux résultats mis en cache en émettant à nouveau la même requête avec l'indicateur de requête enableResultCacheWithTTL. Par exemple :

g.with('Neptune#enableResultCacheWithTTL', 140) .V().has('genre','drama').in('likes')

Tant que 120 secondes ne se sont pas écoulées (ce qui correspond au TTL actuellement en vigueur), cette nouvelle requête avec l'indicateur enableResultCacheWithTTL renvoie les résultats mis en cache. Après 120 secondes, il renverrait de nouveaux résultats et les mettrait en cache avec un time-to-live délai de 140 secondes.

Note

Si les résultats d'une clé de requête sont déjà mis en cache, la même clé de requête enableResultCacheWithTTL ne génère pas de nouveaux résultats et n'a aucun effet sur les time-to-live résultats actuellement mis en cache.

  • Si les résultats ont déjà été mis en cache avec enableResultCache, le cache doit d'abord être explicitement vidé avant qu'enableResultCacheWithTTL génère de nouveaux résultats et les mette en cache pour le TTL qu'il spécifie.

  • Si les résultats ont déjà été mis en cache à l'aide de l'indicateur enableResultCachewithTTL, cette durée de vie précédente, ou TTL, doit d'abord expirer avant qu'enableResultCacheWithTTL génère de nouveaux résultats et les mette en cache pour la durée de vie qu'il spécifie.

Utiliser invalidateResultCacheKey

Vous pouvez utiliser l'indicateur de requête invalidateResultCacheKey pour effacer les résultats mis en cache pour une requête particulière. Par exemple :

g.with('Neptune#invalidateResultCacheKey', true) .V().has('genre','drama').in('likes')

Cette requête vide la partie du cache correspondant à la clé de requête, g.V().has('genre','drama').in('likes'), et renvoie de nouveaux résultats pour cette requête.

Vous pouvez également combiner invalidateResultCacheKey avec enableResultCache ou enableResultCacheWithTTL. Par exemple, la requête suivante efface les résultats actuellement mis en cache, met en cache les nouveaux résultats et les renvoie :

g.with('Neptune#enableResultCache', true) .with('Neptune#invalidateResultCacheKey', true) .V().has('genre','drama').in('likes')

Utiliser invalidateResultCache

Vous pouvez utiliser l'indicateur de requête invalidateResultCache pour effacer tous les résultats mis en cache dans le cache des résultats de requête. Par exemple :

g.with('Neptune#invalidateResultCache', true) .V().has('genre','drama').in('likes')

Cette requête vide l'intégralité du cache de résultats et renvoie de nouveaux résultats pour la requête.

Vous pouvez également combiner invalidateResultCache avec enableResultCache ou enableResultCacheWithTTL. Par exemple, la requête suivante vide l'intégralité du cache de résultats, met en cache les nouveaux résultats pour cette requête et les renvoie :

g.with('Neptune#enableResultCache', true) .with('Neptune#invalidateResultCache', true) .V().has('genre','drama').in('likes')

Pagination des résultats de requête mis en cache

Supposons que vous ayez déjà mis en cache un grand nombre de résultats comme suit :

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

Supposons maintenant que vous émettiez la requête de plage suivante :

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes').range(0,10)

Neptune recherche d'abord la clé de cache complète, à savoir g.V().has('genre','drama').in('likes').range(0,10). Si elle n'existe pas, Neptune vérifie ensuite s'il existe une clé pour cette chaîne de requête sans la plage (à savoir g.V().has('genre','drama').in('likes')). Lorsqu'il trouve cette clé, Neptune extrait les dix premiers résultats de son cache, conformément à la plage spécifiée.

Note

Si vous utilisez l'indicateur invalidateResultCacheKey avec une requête contenant une plage à la fin, Neptune vide la partie du cache correspondant à une requête sans plage s'il ne trouve pas de correspondance exacte entre cette requête et cette plage.

Utilisation d’numResultsCached avec .iterate()

À l'aide de l'indicateur de requête numResultsCached, vous pouvez remplir le cache de résultats sans avoir à renvoyer tous les résultats mis en cache, ce qui peut être utile lorsque vous préférez paginer un grand nombre de résultats.

L'indicateur de requête numResultsCached ne fonctionne qu'avec les requêtes se terminant par iterate().

Par exemple, si vous souhaitez mettre en cache les 50 premiers résultats de cet exemple de requête :

g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').iterate()

Dans ce cas, la clé de requête dans le cache est : g.with("Neptune#numResultsCached", 50).V().has('genre','drama').in('likes'). Vous pouvez désormais récupérer les 10 premiers résultats mis en cache avec cette requête :

g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').range(0, 10)

Et vous pouvez récupérer les 10 résultats suivants de la requête comme suit :

g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').range(10, 20)

N'oubliez pas d'inclure l'indicateur numResultsCached. Il s'agit d'un élément essentiel de la clé de requête. Il doit donc être présent pour pouvoir accéder aux résultats mis en cache.

Voici quelques points à garder à l'esprit lorsque vous utilisez numResultsCached :
  • Le nombre que vous indiquez avec numResultsCached est appliqué à la fin de la requête.   Cela signifie, par exemple, que la requête suivante met réellement en cache les résultats dans la plage (1000, 1500) :

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 500) .V().range(1000, 2000).iterate()
  • Le nombre que vous indiquez avec numResultsCached spécifie le nombre maximum de résultats à mettre en cache.   Cela signifie, par exemple, que la requête suivante met réellement en cache les résultats dans la plage (1000, 2000) :

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 100000) .V().range(1000, 2000).iterate()
  • Les résultats mis en cache par les requêtes se terminant par .range().iterate() ont leur propre plage.   Supposons, par exemple, que vous mettiez en cache les résultats à l'aide d'une requête comme celle-ci :

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 500) .V().range(1000, 2000).iterate()

    Pour récupérer les 100 premiers résultats du cache, vous devriez écrire une requête comme celle-ci :

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 500) .V().range(1000, 2000).range(0, 100)

    Ces cent résultats seraient équivalents aux résultats de la requête de base de la plage (1000, 1100).

Clés de cache de requête utilisées pour localiser les résultats mis en cache

Une fois que les résultats d'une requête ont été mis en cache, les requêtes suivantes avec la même clé de cache de requête récupèrent les résultats du cache au lieu d'en générer de nouveaux. La clé de cache d'une requête est évaluée comme suit :

  1. Tous les indicateurs de requête liés au cache sont ignorés, à l'exception de numResultsCached.

  2. Une dernière étape iterate() est ignorée.

  3. Le reste de la requête est ordonné en fonction de sa représentation en bytecode.

La chaîne générée est comparée à un index des résultats de requête déjà présents dans le cache afin de déterminer la requête a accédé au cache.

Prenons, par exemple, cette requête :

g.withSideEffect('Neptune#typePromotion', false).with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').iterate()

Elle sera stockée en tant que version bytecode de celle-ci :

g.withSideEffect('Neptune#typePromotion', false) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes')

Exceptions liées au cache de résultats

Si les résultats d'une requête que vous essayez de mettre en cache sont trop importants pour tenir dans la mémoire du cache, même après avoir supprimé tout ce qui était déjà mis en cache, Neptune signale une erreur QueryLimitExceededException. Aucun résultat n'est renvoyé, et l'exception génère le message d'erreur suivant :

The result size is larger than the allocated cache, please refer to results cache best practices for options to rerun the query.

Vous pouvez supprimer ce message à l'aide de l'indicateur de requête noCacheExceptions, comme suit :

g.with('Neptune#enableResultCache', true) .with('Neptune#noCacheExceptions', true) .V().has('genre','drama').in('likes')