Cache intégré d'Azure Cosmos DB - Présentation

S’APPLIQUE À : NoSQL

Le cache intégré Azure Cosmos DB est un cache en mémoire qui vous permet de garantir des coûts gérables et une faible latence à mesure que le volume de vos requêtes augmente. Le cache intégré est facile à configurer et vous n’avez pas besoin de passer du temps à écrire du code personnalisé pour l’invalidation du cache ou la gestion de l’infrastructure principale. Le cache intégré utilise la passerelle dédiée au sein de votre compte Azure Cosmos DB. Lors de l’approvisionnement de votre passerelle dédiée, vous pouvez choisir le nombre de nœuds et la taille des nœuds en fonction du nombre de cœurs et de la mémoire nécessaires pour votre charge de travail. Chaque passerelle dédiée possède un cache intégré distinct des autres.

Un cache intégré est automatiquement configuré dans la passerelle dédiée. Le cache intégré comporte deux parties :

  • Un cache d’éléments pour les lectures de point
  • Un cache de requêtes pour les requêtes

Le cache intégré est un cache de lecture-écriture, accessible en écriture, avec une stratégie d’éviction Le moins récemment utilisé (LRU). Le cache d’éléments et le cache de requêtes partagent la même capacité dans le cache intégré, et la stratégie d’éviction du dernier récemment utilisé (LRU) s’applique aux deux. Les données sont supprimées du cache de façon stricte en fonction du moment où elles ont été utilisées le moins récemment, qu’il s’agisse d’une lecture ou d’une requête de point. Les données mises en cache dans chaque nœud dépendent des données qui ont été écrites ou lues récemment par ce nœud spécifique. Si un élément ou une requête est mis en cache sur un nœud, il ne l’est pas nécessairement sur les autres.

Notes

Avez-vous des commentaires sur le cache intégré ? Nous attendons vos remarques ! N’hésitez pas à partager vos commentaires directement avec l’équipe d’ingénieurs Azure Cosmos DB : cosmoscachefeedback@microsoft.com

Charges de travail qui tirent parti du cache intégré

L’objectif principal du cache intégré est de réduire les coûts liés aux charges de travail lourdes en lecture. Une faible latence, bien qu’utile, n’est pas l’avantage principal du cache intégré, car Azure Cosmos DB est déjà rapide sans mise en cache.

Les lectures et requêtes de points qui atteignent le cache intégré ont un coût de RU de 0. Les correspondances dans le cache présentent un coût par opération nettement inférieur à celui des lectures de la base de données back-end.

Pour les charges de travail qui correspondent aux caractéristiques suivantes, vous devez évaluer si le cache intégré permet de réduire les coûts :

  • Charges de travail nécessitant beaucoup de lectures
  • Nombreuses lectures de point répétées sur des éléments volumineux
  • Nombreuses requêtes à RU élevées répétitives
  • Clé de partition à chaud pour les lectures

Le plus grand facteur d’économie attendu est la mesure dans laquelle les lectures se répètent. Si votre charge de travail exécute régulièrement les mêmes lectures de point ou requêtes dans un laps de temps réduit, il s’agit d’un bon candidat pour le cache intégré. Lorsque vous utilisez le cache intégré pour des lectures répétées, vous utilisez uniquement les RU pour la première lecture. Les lectures suivantes acheminées via le même nœud dédié de passerelle (dans la fenêtre MaxIntegratedCacheStaleness et si les données n’ont pas été supprimées) n’utilisent pas le débit.

Certaines charges de travail ne doivent pas prendre en compte le cache intégré, notamment :

  • Charges de travail nécessitant beaucoup d’écritures
  • Lectures de point ou requêtes rarement répétées
  • Charges de travail lisant le flux de modification

Cache d’éléments

Le cache d’éléments est utilisé pour les lectures de points (recherches de clé/valeur en fonction de l’ID d’élément et de la clé de partition).

Remplissage du cache d’éléments

  • Les nouvelles écritures, mises à jour et suppressions sont automatiquement renseignées dans le cache d’éléments du nœud via lequel la demande est acheminée.
  • Les éléments des demandes de lecture de point où l’élément n’est pas déjà dans le cache (absence dans le cache) du nœud via lequel la demande est acheminée sont ajoutés au cache d’éléments.
  • Les requêtes qui font partie d’un lot transactionnel ou qui sont en mode en bloc ne remplissent pas le cache d’éléments

Invalidation et éviction du cache d’éléments

Étant donné que chaque nœud dispose d’un cache indépendant, il est possible que des éléments soient invalidés ou supprimés dans le cache d’un nœud et pas dans les autres. Les éléments du cache d’un nœud donné sont invalidés et supprimés en fonction des critères ci-dessous :

  • Mise à jour ou suppression d’élément
  • Dernier récemment utilisé (LRU)
  • Durée de rétention du cache (en d’autres termes, MaxIntegratedCacheStaleness)

Cache de requête

Le cache de requêtes est utilisé pour mettre en cache des requêtes. Il transforme une requête en une recherche de clé/valeur où la clé est le texte de la requête et la valeur est le résultat de la requête. Le cache intégré ne dispose pas d’un moteur de requête, il stocke uniquement la recherche de clé/valeur pour chaque requête. Les résultats de la requête sont stockés dans un jeu et le cache ne suit pas les éléments individuels. Un élément donné peut être stocké plusieurs fois dans le cache de requêtes s’il apparaît dans le jeu de résultats de plusieurs requêtes. Les mises à jour des éléments sous-jacents ne seront pas répercutées dans les résultats de la requête, sauf si l’obsolescence maximale du cache intégré pour la requête est atteinte et que la requête est traitée depuis la base de données back-end.

Remplissage du cache de requêtes

  • Si le cache n’a pas de résultat pour cette requête (absence dans le cache) sur le nœud via lequel elle a été acheminée, la requête est envoyée au back-end. Une fois la requête exécutée, le cache stocke les résultats de cette requête
  • Les requêtes avec la même forme mais qui ont des paramètres ou des options de requête différents qui affectent les résultats (par exemple le nombre maximal d’éléments) sont stockées sous la forme de leur propre paire clé/valeur.

Éviction du cache de requêtes

La suppression du cache de requêtes est basée sur le nœud via lequel la demande a été acheminée. Il est possible que des requêtes soient supprimées ou actualisées sur un nœud et non sur les autres.

  • Dernier récemment utilisé (LRU)
  • Durée de rétention du cache (en d’autres termes, MaxIntegratedCacheStaleness)

Utilisation du cache de requêtes

Vous n’avez pas besoin de code spécial lorsque vous travaillez avec le cache de requêtes, même si vos requêtes comportent plusieurs pages de résultats. Les bonnes pratiques et le code pour la pagination de requête sont les mêmes que votre requête accède au cache intégré ou s’exécute sur le moteur de requête principal.

Le cache de requêtes met automatiquement en cache les jetons de continuation de requête, le cas échéant. Si vous avez une requête avec plusieurs pages de résultats, les pages qui sont stockées dans le cache intégré ont une charge de 0 RU. Si vous avez d’autres pages de résultats de requête qui requièrent l’exécution du back-end, elles disposeront d’un jeton de continuation de la page précédente afin d’éviter de dupliquer le travail précédent.

Important

Les instances de cache intégrées dans différents nœuds de passerelle dédiés ont des caches indépendants les uns des autres. Si les données sont mises en cache dans un nœud, elles ne sont pas nécessairement mises en cache dans les autres. Il n’est pas garanti que plusieurs pages d’une même requête soient routées vers le même nœud de passerelle dédiée.

Cohérence du cache intégré

Le cache intégré prend uniquement en charge les demandes de lecture avec une cohérence de session et à terme. Si une lecture a constamment un préfixe, une obsolescence limitée ou une cohérence forte, elle contourne le cache intégré et est traitée à partir du back-end.

Le moyen le plus simple de configurer une session ou une cohérence éventuelle pour toutes les lectures est de le définir au niveau du compte. Toutefois, si vous souhaitez que certaines de vos lectures aient une cohérence spécifique, vous pouvez également configurer la cohérence au niveau de la requête.

Notes

Les demandes d’écriture avec d’autres cohérences remplissent toujours le cache, mais pour une lecture à partir du cache, la demande doit avoir une cohérence de session ou à terme.

Cohérence de session

La cohérence de session est le niveau de cohérence le plus largement utilisé pour les comptes Azure Cosmos DB à région unique et globalement distribués. Grâce à la cohérence de session, les sessions client uniques peuvent lire leurs propres écritures. Toutes les lectures avec cohérence de session et sans jeton de session correspondant entraînent des frais RU. Cela comprend la première requête pour un élément ou une requête donné lorsque l’application cliente est démarrée ou redémarrée, sauf si vous transmettez explicitement un jeton de session valide. Quand ils utilisent le caché intégré, les clients en dehors de la session effectuant des écritures voient la cohérence éventuelle.

MaxIntegratedCacheStaleness

MaxIntegratedCacheStalenessest l’obsolescence maximale acceptable pour les lectures et les requêtes de points mis en cache, quelle que soit la cohérence sélectionnée. MaxIntegratedCacheStaleness est configurable au niveau de la demande. Par exemple, si vous définissez MaxIntegratedCacheStaleness sur 2  heures, votre demande retourne uniquement les données mises en cache si celles-ci ont moins de 2 heures. Pour augmenter la probabilité que les lectures répétées utilisent le cache intégré, vous devez définir MaxIntegratedCacheStaleness avec une valeur aussi élevée que vos besoins métier le permettent.

MaxIntegratedCacheStaleness, quand elle est configurée sur une requête qui finit par remplir le cache, n’a pas d’impact sur la durée de mise en cache de la requête. MaxIntegratedCacheStaleness applique la cohérence quand vous essayez d’utiliser des données mises en cache. Il n’existe pas de paramètre de durée de vie globale ou de conservation du cache, donc les données sont supprimées du cache seulement si le cache intégré est plein ou si une nouvelle lecture est exécutée avec une MaxIntegratedCacheStaleness inférieure à l’ancienneté de l’entrée mise en cache actuelle.

Il s’agit d’une amélioration par rapport à la façon dont la plupart des caches fonctionnent et elle permet les autres personnalisations suivantes :

  • Vous pouvez définir différentes exigences d’obsolescence pour chaque lecture ou requête de point.
  • Les différents clients, même s’ils exécutent la même lecture ou requête de point, peuvent configurer différentes valeurs pour MaxIntegratedCacheStaleness
  • Si vous souhaitez modifier la cohérence de lecture pour les données mises en cache, changer MaxIntegratedCacheStaleness a un effet immédiat sur la cohérence de lecture.

Notes

La valeur minimale de MaxIntegratedCacheStaleness est 0, alors que la valeur maximale est 10 ans. Lorsqu’elle n’est pas explicitement configurée, la valeur par défaut de MaxIntegratedCacheStaleness est de 5 minutes.

Pour mieux comprendre le paramètre MaxIntegratedCacheStaleness, regardez l’exemple suivant :

Temps Requête response
t = 0 sec Exécuter la requête A avec MaxIntegratedCacheStaleness = 30 secondes Retourner les résultats de la base de données back-end (frais RU normaux) et remplir le cache
t = 0 sec Exécuter la requête B avec MaxIntegratedCacheStaleness = 60 secondes Retourner les résultats de la base de données back-end (frais RU normaux) et remplir le cache
t = 20 sec Exécuter la requête A avec MaxIntegratedCacheStaleness = 30 secondes Retourner les résultats du cache intégré (0 RU facturée)
t = 20 sec Exécuter la requête B avec MaxIntegratedCacheStaleness = 60 secondes Retourner les résultats du cache intégré (0 RU facturée)
t = 40 sec Exécuter la requête A avec MaxIntegratedCacheStaleness = 30 secondes Retourner les résultats de la base de données back-end (frais RU normaux) et actualiser le cache
t = 40 sec Exécuter la requête B avec MaxIntegratedCacheStaleness = 60 secondes Retourner les résultats du cache intégré (0 RU facturée)
t = 50 sec Exécuter la requête B avec MaxIntegratedCacheStaleness = 20 secondes Retourner les résultats de la base de données back-end (frais RU normaux) et actualiser le cache

Apprenez à configurer MaxIntegratedCacheStaleness.

Contourner le cache intégré (préversion)

Le cache intégré a une capacité de stockage limitée, déterminée par la référence SKU de la passerelle dédiée provisionnée. Par défaut, toutes les requêtes des clients configurés avec la chaîne de connexion de passerelle dédiée passent par le cache intégré et occupent de l’espace dans celui-ci. Vous pouvez contrôler quels éléments et quelles requêtes sont mis en cache avec l’option de contournement du cache intégré par les requêtes, qui est actuellement en préversion. Cette option de requête est utile pour les écritures d’éléments ou les requêtes en lecture qui ne sont normalement pas répétées fréquemment. Le contournement du cache intégré pour les éléments faisant l’objet d’accès peu fréquents permet d’économiser de l’espace du cache pour les éléments avec plus de répétitions, d’augmenter le potentiel d’économie des RU (unités de requête) et de réduire les évictions. Les requêtes qui ignorent le cache sont néanmoins toujours routées via la passerelle dédiée. Ces requêtes sont traitées depuis le back-end et engendrent des coûts en RU.

Découvrir comment contourner le cache intégré

Métriques

Il est utile de surveiller quelques métriques clés pour le cache intégré. Ces métriques incluent :

  • DedicatedGatewayCPUUsage : utilisation du processeur avec les types d’agrégation Moyenne, Maximum ou Minimum pour les données sur tous les nœuds de passerelle dédiée.
  • DedicatedGatewayAverageCPUUsage : (déprécié) utilisation moyenne du processeur sur tous les nœuds de passerelle dédiée.
  • DedicatedGatewayMaximumCPUUsage : (déprécié) utilisation maximale du processeur sur tous les nœuds de passerelle dédiée.
  • DedicatedGatewayMemoryUsage : utilisation de la mémoire avec les types d’agrégation Moyenne, Maximum ou Minimum pour les données sur tous les nœuds de passerelle dédiée.
  • DedicatedGatewayAverageMemoryUsage : (déprécié) utilisation moyenne de la mémoire sur tous les nœuds de passerelle dédiée.
  • DedicatedGatewayRequests : nombre total de demandes de passerelle dédiée sur tous les nœuds de passerelle dédiée.
  • IntegratedCacheEvictedEntriesSize : quantité moyenne de données supprimées du cache intégré en raison du LRU sur tous les nœuds de passerelle dédiée. Cette valeur n’inclut pas les données qui ont expiré en raison du dépassement de la durée de MaxIntegratedCacheStaleness.
  • IntegratedCacheItemExpirationCount : nombre moyen d’éléments supprimés du cache intégré en raison des lectures de point mises en cache qui dépassent la durée de MaxIntegratedCacheStaleness sur tous les nœuds de passerelle dédiée.
  • IntegratedCacheQueryExpirationCount : nombre moyen de requêtes supprimées du cache intégré en raison des requêtes mises en cache qui dépassent la durée de MaxIntegratedCacheStaleness sur tous les nœuds de passerelle dédiée.
  • IntegratedCacheItemHitRate - Proportion de lectures de point qui ont utilisé le cache intégré (par rapport à toutes les lectures de point acheminées via la passerelle dédiée avec session ou cohérence finale). Cette valeur est une moyenne des instances du cache intégré sur tous les nœuds de passerelle dédiée.
  • IntegratedCacheQueryHitRate - Proportion de requêtes qui ont utilisé le cache intégré (par rapport à toutes les requêtes acheminées via la passerelle dédiée avec session ou cohérence finale). Cette valeur est une moyenne des instances du cache intégré sur tous les nœuds de passerelle dédiée.

Toutes les métriques existantes sont disponibles, par défaut, dans Métriques dans le portail Azure (pas les métriques classiques) :

Screenshot of the Azure portal that shows the location of integrated cache metrics.

Les métriques représentent une moyenne, une valeur maximale ou une somme pour tous les nœuds de passerelle dédiée. Par exemple, si vous provisionnez un cluster de passerelle dédié avec cinq nœuds, les métriques reflètent la valeur agrégée sur les cinq nœuds. Il n’est pas possible de déterminer les valeurs de métrique pour chaque nœud individuel.

Dépannage des problèmes courants

Les exemples ci-dessous montrent comment déboguer certains scénarios courants :

Je ne peux pas savoir si mon application utilise la passerelle dédiée

Vérifiez DedicatedGatewayRequests. Cette métrique comprend toutes les requêtes qui utilisent la passerelle dédiée, qu’elles aient une correspondance ou non dans le cache intégré. Si votre application utilise la passerelle standard ou le mode direct avec votre chaîne de connexion d’origine, vous ne verrez pas de message d’erreur, mais DedicatedGatewayRequests sera égal à zéro. Si votre application utilise le mode direct avec votre chaîne de connexion de passerelle dédiée, vous verrez peut-être un petit nombre de DedicatedGatewayRequests.

Je ne peux pas savoir si mes demandes ont une correspondance dans le cache intégré

Regardez IntegratedCacheItemHitRate et IntegratedCacheQueryHitRate. Si ces deux valeurs sont égales à zéro, les demandes n’atteignent pas le cache intégré. Vérifiez que vous utilisez la chaîne de connexion de passerelle dédiée, que vous vous connectez avec le mode passerelle et que vous utilisez la session ou la cohérence à terme.

Je souhaite comprendre si ma passerelle dédiée est trop petite

Regardez IntegratedCacheItemHitRate et IntegratedCacheQueryHitRate. Des valeurs élevées (par exemple, au-delà de 0,7-0,8) indiquent que la passerelle dédiée est suffisamment grande.

Si IntegratedCacheItemHitRate ou IntegratedCacheQueryHitRate est bas, regardez IntegratedCacheEvictedEntriesSize. Si IntegratedCacheEvictedEntriesSize a une valeur élevée, cela peut signifier qu’une plus grande taille de passerelle dédiée serait avantageuse. Vous pouvez essayer en agrandissant la taille de la passerelle dédiée et en comparant les nouveaux IntegratedCacheItemHitRate et IntegratedCacheQueryHitRate. Si une plus grande passerelle dédiée n’améliore pas IntegratedCacheItemHitRate ou IntegratedCacheQueryHitRate, il est possible que ce soit juste les lectures qui ne se répètent pas assez pour que le cache intégré ait un impact.

Je souhaite comprendre si ma passerelle dédiée est trop volumineuse

Il est plus difficile de mesurer si une passerelle dédiée est trop grande que de mesurer si une passerelle dédiée est trop petite. En général, vous devez commencer petit et lentement augmenter la taille de la passerelle dédiée jusqu’à ce que IntegratedCacheItemHitRate et IntegratedCacheQueryHitRate cessent de s’améliorer. Dans certains cas, une seule des deux métriques d’accès au cache est importante, pas les deux. Par exemple, si votre charge de travail est principalement des requêtes plutôt que des lectures de point, IntegratedCacheQueryHitRate est bien plus important que IntegratedCacheItemHitRate.

Si la plupart des données sont supprimées du cache en raison du dépassement de MaxIntegratedCacheStaleness, plutôt que du LRU, votre cache peut être plus grand que nécessaire. Si IntegratedCacheItemExpirationCount et IntegratedCacheQueryExpirationCount ensemble sont presque aussi élevés que IntegratedCacheEvictedEntriesSize, vous pouvez faire des essais avec une plus petite taille de passerelle dédiée et comparer les performances.

Je souhaite savoir si j’ai besoin d’ajouter d’autres nœuds de passerelle dédiée

Dans certains cas, si la latence est anormalement élevée, vous pouvez avoir besoin d’un plus grand nombre de nœuds de passerelle dédiée plutôt que de plus grands nœuds. Regardez DedicatedGatewayCPUUsage et DedicatedGatewayMemoryUsage pour déterminer si l’ajout de nœuds de passerelle dédiée supplémentaires réduirait la latence. Il est bon de se rappeler que puisque toutes les instances du cache intégré sont indépendantes les unes des autres, l’ajout de nœuds de passerelle dédiée supplémentaires ne réduit pas IntegratedCacheEvictedEntriesSize. Toutefois, l’ajout de nœuds supplémentaires améliore le volume de requêtes que votre cluster de passerelle dédiée peut gérer.

Étapes suivantes