Unité 5.5 : Base de données en mémoire (couche de cache)
Introduction
L'unité 5.3 a défini une limite stricte de la plateforme : PostgreSQL et MariaDB gérés sur IONOS CLOUD ne disposent d'aucune réplique en lecture, d'aucune réplication gérée vers un second cluster et d'aucune réplication inter-régions. Les répliques synchrones et asynchrones au sein d'un cluster existent pour la bascule en cas de défaillance, et non pour traiter le trafic de lecture. Cela soulève une question évidente pour toute charge de travail intensive en lecture : d'où provient la mise à l'échelle de la lecture ? La réponse se trouve dans cette unité. La couche de cache In-Memory DB absorbe la charge de lecture qu'une réplique de lecture relationnelle aurait supportée, et en le faisant, elle comble l'absence de répliques de lecture par un modèle natif plutôt que par une fonctionnalité manquante.
Cette même couche remplit une seconde fonction tout aussi importante. L'unité 4.3 a montré que VM Auto Scaling ne peut ajouter et supprimer des répliques sans état en toute sécurité. Toute session, verrou ou état transitoire résidant dans la mémoire d'un nœud de calcul est perdu dès que ce nœud est retiré. L'externalisation de cet état vers une couche mémoire partagée est ce qui rend la couche application véritablement sans état, et par conséquent ce qui rend la mise à l'échelle automatique sûre. Cette unité se termine par la création du cluster dans Data Center Designer et sa connexion sur le réseau privé, en amont de la couche relationnelle.
1. La couche de mise à l'échelle en lecture et d'externalisation de l'état
In-Memory DB est proposé via IONOS CLOUD DBaaS sous forme de magasin de paires clé-valeur géré, compatible avec Redis OSS, et verrouillé sur la version stable 7.2 de Redis OSS. Il s'agit d'un serveur de structures de données, et non d'un simple cache à plat : il stocke des chaînes de caractères, des hachages, des listes, des ensembles, des ensembles ordonnés, des bitmaps, des hyperloglogs, des index géospatiaux et des flux. Cette diversité permet à une seule couche d'assumer deux rôles architecturaux simultanément.
Pourquoi il remplace les répliques de lecture. Une réplique de lecture relationnelle met à l'échelle les lectures en dupliquant le jeu de données sur un autre nœud qui répond aux requêtes SELECT ; IONOS CLOUD DBaaS n'offre pas cette possibilité. En revanche, l'application lit à travers un cache : la première requête pour une valeur manque et interroge PostgreSQL ou MariaDB, le résultat est écrit dans In-Memory DB, et chaque requête suivante est servie depuis la mémoire avec une latence inférieure à la milliseconde, sans toucher à la base de données. L'utilisation du cache minimise les requêtes vers la base de données, réduisant considérablement le trafic et les ressources nécessaires, et permettant une couche de mise à l'échelle rapide et économique. La base de données relationnelle principale reste petite car elle ne voit que les manques de cache et les écritures, tandis que le débit de lecture augmente avec la mémoire du cache plutôt qu'avec le nombre de cœurs de la base de données. C'est le choix de conception signalé dans l'unité 2.4 comme mise à l'échelle par cache : on achète de la RAM dans la couche de cache au lieu de mettre à l'échelle verticalement la base de données.
Pourquoi c'est la condition préalable à la mise à l'échelle automatique. Lorsque la couche d'application conserve l'état des sessions en mémoire de processus locale, chaque événement de réduction de taille détruit les sessions attachées au nœud supprimé, et chaque extension démarre un nœud froid invisible aux autres requêtes. Déplacer l'état des sessions et l'état transitoire vers la couche In-Memory DB partagée signifie que n'importe quelle réplique de calcul peut servir n'importe quelle requête, ce qui est exactement la condition préalable sans état exigée par l'unité 4.3 avant qu'un groupe de mise à l'échelle automatique piloté par des métriques puisse ajouter ou supprimer des nœuds Dedicated Core sans perturber les utilisateurs. La couche de cache est donc la moitié lecture du schéma sans réplique de lecture (5.3) et la moitié externalisation de l'état de la mise à l'échelle automatique sécurisée (4.3).
Ce que la mise à l'échelle du cache fait et ne fait pas. Un cluster In-Memory DB se met à l'échelle de deux manières, et la distinction est facile à confondre. La mise à l'échelle verticale modifie les cœurs et la RAM par nœud et c'est ainsi que l'on augmente le débit ; les nœuds sont modifiés après avoir été arrêtés, de sorte que les clusters multi-nœuds minimisent les perturbations en modifiant d'abord les secondaires, puis le primaire. La mise à l'échelle horizontale modifie le nombre de nœuds, mais la documentation est explicite : elle ne fournit que la haute disponibilité et n'augmentera pas les performances : le primaire accepte toutes les lectures et les écritures, et les secondaires constituent une capacité en attente pour la bascule automatique, et non des points de lecture supplémentaires. Le cache met donc à l'échelle les lectures par la taille de la mémoire, et non en répartissant les lectures sur des répliques, reflétant la réalité sans réplique de lecture de la couche relationnelle, un niveau au-dessus.
1.1 FinCorp : combler le déficit de mise à l'échelle en lecture
Le chemin de lecture du portail client de FinCorp était le problème non résolu laissé par l'unité 5.3. Les vues de récapitulatif de compte et d'historique des transactions sont lues beaucoup plus souvent qu'elles ne sont écrites, et le cluster PostgreSQL régulé sur la couche de données privée ne peut pas être mis à l'échelle en ajoutant des répliques de lecture. FinCorp place un cluster In-Memory DB sur le même LAN privé, devant le cluster PostgreSQL, et achemine les lectures du portail à travers celui-ci. Les récapitulatifs de compte fréquemment consultés sont servis depuis la mémoire ; la base de données n'est touchée qu'en cas de manque de cache ou d'écriture. Le même cluster conserve l'état des sessions du portail, de sorte que la couche web publique sans état peut être placée sous le groupe de mise à l'échelle automatique Dedicated Core conçu dans l'unité 4.3 sans perdre de sessions lorsque les nœuds sont réduits. Une couche gérée unique résout les deux contraintes, et elle ne quitte jamais le réseau privé.
2. Cache-Aside vs Write-Through
Le cache n'est utile que si l'application l'intègre selon une stratégie de lecture et d'écriture délibérée. Deux modèles prédominent, et le choix relève d'une décision d'architecture applicative que la plateforme ne prend pas à votre place.
Le tableau suivant met en contraste les deux modèles d'intégration :
| Modèle | Fonctionnement des lectures | Fonctionnement des écritures | Meilleur usage | Risque principal |
|---|---|---|---|---|
| Cache-aside (chargement différé) | L'application vérifie le cache ; en cas d'échec, elle lit la base de données, puis alimente le cache | L'application écrit dans la base de données et invalide ou met à jour la clé du cache | Charges de travail à forte intensité de lecture où toutes les données ne sont pas chaudes | Entrées obsolètes si l'invalidation est omise ; la première lecture d'une clé donnée échoue toujours |
| Write-through | L'application lit depuis le cache (supposé alimenté) | L'application écrit dans le cache et dans la base de données de manière synchrone, en tant qu'une seule étape logique | Charges de travail nécessitant des données fraîchement mises en cache immédiatement après une écriture | Latence d'écriture plus élevée ; le cache contient des données qui ne seront peut-être jamais lues |
Cache-aside est le modèle par défaut pour une couche de mise à l'échelle en lecture, car il ne met en cache que les données réellement demandées, ce qui concentre la mémoire du cache sur le jeu de travail actif. Son coût est l'échec à froid lors du premier accès et la discipline d'invalider ou de rafraîchir une clé à chaque écriture, afin que le cache ne serve pas une valeur obsolète après une modification de la base de données. Pour le portail de FinCorp, où un petit ensemble de comptes est constamment lu et la plupart rarement, le cache-aside maintient le jeu de travail actif en mémoire et laisse la longue traîne à la base de données.
Write-through maintient le cache comme source autoritaire immédiatement après une écriture en écrivant simultanément dans les deux dépôts, ce qui convient aux données lues très peu de temps après leur écriture. Il paie cette fraîcheur par une latence d'écriture accrue, car chaque écriture attend désormais les deux dépôts, et il peut remplir le cache d'entrées qui ne seront jamais relues par la suite.
Une règle pratique : choisissez une durée de vie (Time To Live) pour les clés mises en cache qui correspond à l'obsolescence acceptable d'une valeur, et considérez l'éviction comme un filet de sécurité, et non comme le mécanisme principal d'expiration. Étant donné que le cache se substitue à la mise à l'échelle en lecture et n'est pas un système de référence, l'application doit toujours pouvoir reconstruire n'importe quelle valeur à partir de la couche relationnelle en cas d'échec. Les options de persistance ci-dessous renforcent le cache contre les redémarrages, mais le cluster relationnel reste la source de vérité.
3. Placement, dimensionnement et éviction
3.1 Placement sur le réseau privé
In-Memory DB est rattaché à exactement une connexion réseau : une seule connexion LAN privée par cluster, définie par un centre de données, un identifiant LAN et une adresse IP dans le sous-réseau de ce LAN. Il n'y a ni point d'accès public, ni gestion d'adresses IP pour le cluster. Vous choisissez donc une adresse IP dans votre sous-réseau (ou utilisez l'adresse IP du sous-réseau attribuée par la plateforme via DHCP), et le cluster devient accessible à cette adresse après le provisionnement. C'est le même placement sur le niveau de données privé utilisé pour les bases de données relationnelles et documentaires de ce module : le cache est placé sur le LAN privé, en amont du cluster relationnel, accessible uniquement depuis le niveau applicatif et le niveau de base de données, et jamais depuis Internet. Les clients se connectent via TLS uniquement si le cluster a été explicitement configuré pour l'utiliser (TLS n'est pas activé par défaut), le certificat serveur étant émis par Let's Encrypt lorsqu'il est activé. L'architecte doit donc décider d'activer TLS, puis le client doit se connecter avec l'option TLS et le certificat d'autorité de certification correspondant.
Les plages d'adresses IP suivantes sont réservées par la plateforme et ne peuvent pas être utilisées pour les connexions In-Memory DB :
| Plage réservée |
|---|
| 10.208.0.0/12 |
| 10.233.0.0/18 |
| 192.168.230.0/24 |
| 10.233.64.0/18 |
3.2 Dimensionnement à partir de la RAM et de la persistance
Vous ne provisionnez pas directement le disque du cache. Vous choisissez le nombre de cœurs CPU et la quantité de RAM par nœud, et la plateforme déduit le Block Storage provisionné à partir de la RAM configurée et du mode de persistance choisi, avec un minimum de 10 Go par nœud appliqué pour tous les modes. La relation est fixe :
| Persistance des données | Stockage provisionné |
|---|---|
| Aucune | 1 x RAM |
| RDB | 2 x RAM |
| AOF | 4 x RAM |
| RDB et AOF | 8 x RAM |
Le mode de persistance est le levier de dimensionnement le plus important. La valeur par défaut est Aucune, ce qui signifie que le jeu de données n'existe qu'en mémoire et est perdu lors d'un redémarrage. Pour un cache de lecture pure qui peut toujours se reconstruire à partir du niveau relationnel, Aucune est souvent le choix le plus correct et le moins coûteux. RDB écrit des instantanés périodiques à un instant donné ; AOF journalise chaque opération d'écriture et peut reconstruire le jeu de données lors d'un redémarrage ; RDB_AOF combine les deux pour la configuration la plus durable, et la plus gourmande en stockage. Le compromis est direct : plus la durabilité est élevée, plus le stockage provisionné est multiplié par rapport à la RAM. Ainsi, un nœud de 32 Go dimensionné au maximum coûte 32 Go de disque en mode Aucune, mais 256 Go en mode RDB et AOF. Dimensionnez la RAM en fonction de votre ensemble de travail actif, en ajoutant une marge pour l'éviction, puis choisissez le mode de persistance le plus bas que les exigences de récupération de la charge de travail permettent.
Les limites strictes, par rapport à votre quota de contrat, sont un maximum de 16 cœurs CPU, 32 Go de RAM et 2 To de stockage par cluster, avec un maximum de 5 nœuds par cluster. Le moteur Valkey sous-jacent est configuré par défaut pour un maximum de 10 000 connexions clients (maxclients), ce qui est une valeur par défaut technologique et non une limite publiée par IONOS CLOUD.
3.3 Éviction
Lorsqu'un nœud de cache atteint sa limite de mémoire pour les données entrantes, la politique d'éviction détermine ce qui est supprimé. La politique par défaut est allkeys-lru, qui évince la clé utilisée le moins récemment parmi toutes les clés, ce qui est le comportement approprié pour un cache de lecture général où toute clé est candidate à l'éviction. L'ensemble complet des politiques prises en charge est noeviction, allkeys-lru, allkeys-lfu, allkeys-random, volatile-lru, volatile-lfu, volatile-random et volatile-ttl. Les politiques volatile-* n'évictent que les clés qui ont une date d'expiration, ce qui est approprié lorsque certaines clés ne doivent jamais être évincées ; noeviction refuse les nouvelles écritures une fois la mémoire pleine, ce qui transforme le cache en point de défaillance critique et est rarement correct pour un niveau de mise à l'échelle. Pour un niveau de lecture en cache-aside, conservez la politique par défaut allkeys-lru (ou allkeys-lfu si la fréquence d'accès est un meilleur indicateur que la récence) afin que le cache fasse toujours de la place pour l'ensemble de travail actif actuel.
Déroulement de la mise en œuvre de DCD
Ce déroulement provisionne un cluster In-Memory DB unique et le place sur la couche de données privée de FinCorp afin que l'application puisse l'utiliser comme cache de lecture en avant du cluster PostgreSQL de l'Unité 5.3. Le prérequis est un VDC existant avec au moins un serveur sur un LAN privé : le cluster doit rejoindre un LAN privé existant, et vous devez disposer d'une IP dans le sous-réseau de ce LAN pour l'assigner. Réutilisez le VDC et le LAN de couche de données privée de FinCorp créés dans le Module 3.
Objectif de construction : Provisionner le cache et le configurer en tant que couche de lecture.
Étapes (dans Data Center Designer) :
- Dans DCD, accédez à Menu > Bases de données > In-Memory DB. L'aperçu du cluster In-Memory DB s'ouvre et affiche les ressources allouées à votre contrat.
- Cliquez sur Créer un cluster.
- Définissez les propriétés du cluster. Saisissez un Nom de cluster ; laissez la Version sur la valeur par défaut 7.2. Réglez Instances sur le nombre de nœuds : choisissez 1 pour un cache mono-nœud ou jusqu'à 5 pour la haute disponibilité. N'oubliez pas que les nœuds supplémentaires offrent la bascule, et non le débit de lecture. Si vous définissez plus d'un nœud, une option Type de réplication apparaît ; elle est Asynchrone par défaut pour In-Memory DB.
- Sélectionnez le nombre de ressources nécessaires. Utilisez les curseurs pour définir le Nombre de CPU et la Taille de RAM par instance. La RAM est la véritable décision de dimensionnement : dimensionnez-la en fonction de l'ensemble de travail, car le multiplicateur de persistance et le disque par nœud en découlent. Restez dans les limites de 16 cœurs et 32 Go par cluster.
- Connectez le cluster à un VDC. Sélectionnez le centre de données, le LAN privé et une adresse IP (avec CIDR) dans le sous-réseau de ce LAN. Une seule connexion est autorisée par cluster, et elle doit être privée. Choisissez une adresse qui ne entre pas en conflit avec les hôtes existants et qui ne se trouve pas dans une plage réservée.
- Planifiez la maintenance du cluster. Définissez le jour de la semaine et l'heure de début de la fenêtre de maintenance hebdomadaire. Choisissez une période de faible trafic réelle plutôt que de laisser la planification vide, car les mises à niveau de version et les redémarrages s'effectuent ici et peuvent interrompre brièvement les connexions.
- Définissez les utilisateurs. Saisissez un Nom d'utilisateur et un Mot de passe pour le cluster. Ces identifiants ne peuvent être définis qu'au moment de la création et ne peuvent pas être modifiés par la suite ; enregistrez-les donc immédiatement dans votre coffre-fort de secrets.
- Examinez le coût estimé affiché pour la configuration, puis cliquez sur Enregistrer. L'ÉTAT du cluster affiche Occupé pendant la création et Disponible une fois prêt ; la plateforme ne vous notifie pas, donc interrogez l'état jusqu'à ce qu'il devienne Disponible.
Une fois le cluster Disponible, orientez le client de cache de l'application vers l'IP privée assignée sur le port par défaut 6379 (via TLS si vous l'avez activé lors de la configuration de l'instance), et implémentez le chemin de lecture cache-aside de la Section 2 : vérifiez le cache, reprenez sur PostgreSQL en cas de manqué, et remplissez le cache au retour.
Erreurs courantes :
- Considérer les nœuds supplémentaires comme une mise à l'échelle de la lecture. L'ajout de nœuds ne fournit que la haute disponibilité et n'augmente pas les performances ; mettez à l'échelle les lectures avec plus de RAM et un redimensionnement vertical, et non avec plus de répliques.
- Oublier que les identifiants sont définis uniquement à la création. Le nom d'utilisateur et le mot de passe ne peuvent pas être mis à jour ultérieurement, stockez-les donc au moment de la création ; récupérer un mot de passe perdu signifie reconstruire le cluster.
- Laisser la persistance sur la mauvaise couche pour le coût. None perd toutes les données au redémarrage mais provisionne le moins de disque ; RDB et AOF ensemble provisionnent 8 fois la RAM en disque. Pour un cache de lecture pur qui se reconstruit à partir de la base de données, None est généralement correct.
- Choisir
noevictionpour un cache en mise à l'échelle. Lorsque la mémoire est remplie,noevictionrejette les nouvelles écritures et transforme le cache en point de défaillance ; conservez la valeur par défautallkeys-lrusauf si une clé spécifique ne doit jamais être évacuée. - Assigner une IP dans une plage réservée, ou s'attendre à une seconde connexion. Un cluster prend exactement une connexion LAN privée, et les plages réservées par la plateforme (par exemple 10.233.0.0/18) ne peuvent pas être utilisées.
- Ne pas planifier une fenêtre de maintenance réelle. Les mises à niveau et les redémarrages s'exécutent dans la fenêtre hebdomadaire et peuvent interrompre brièvement les connexions, placez-la donc délibérément dans une période calme et assurez-vous que les clients se reconnectent.
Une connexion client brève illustre la contrainte TLS et point d'extrémité privé établie par le texte :
redis-cli -h 192.168.1.100 -p 6379 --tls --cacert ca.crt -a "$PASSWORD" ping
L'hôte est l'IP LAN privée attribuée à l'étape 5, le port est le port par défaut 6379, et la paire --tls --cacert n'est requise que si TLS a été activé lors de la configuration de l'instance (le point de terminaison géré met fin à TLS avec un certificat Let's Encrypt lorsqu'il est activé, mais TLS n'est pas activé par défaut). Il n'y a pas d'adresse publique à laquelle se connecter, et c'est précisément le but : le cache n'est accessible que depuis l'intérieur du VDC.
Résumé
La couche de cache In-Memory DB est le composant unique qui résout simultanément deux limites de la plateforme. Elle constitue le substitut natif des répliques de lecture que les instances gérées PostgreSQL et MariaDB ne proposent pas, en absorbant la charge de lecture via la mémoire afin que l'instance relationnelle principale ne reçoive que les écritures et les manqués de cache. Elle est également le magasin d'état partagé qui rend la couche applicative véritablement sans état, et donc apte à être soumise à VM Auto Scaling. Construite sur la couche de données privée avec un chemin de lecture en cache-aside, dimensionnée à partir de la RAM et du mode de persistance, et laissée sur sa politique d'éviction par défaut raisonnable, elle permet à FinCorp de mettre à l'échelle les lectures et le calcul sans jamais introduire de réplique de lecture de base de données ni de point d'accès public.
Points clés :
- Il n'existe pas de répliques de lecture relationnelles sur IONOS CLOUD ; le cache In-Memory DB est le moyen de mettre à l'échelle les lectures, en servant l'ensemble de travail actif depuis la mémoire et en n'accédant à la base de données qu'en cas de manqué et d'écriture.
- Le cache est également la couche d'externalisation de l'état qui rend réelle la précondition sans état requise pour la mise à l'échelle automatique (Unité 4.3).
- L'ajout de nœuds au cluster fournit la haute disponibilité, et non le débit de lecture ; augmentez la capacité en ajoutant de la RAM et en redimensionnant verticalement.
- Le disque provisionné est dérivé de la RAM multipliée par le multiplicateur de persistance (Aucun 1x, RDB 2x, AOF 4x, RDB+AOF 8x), avec un plancher de 10 Go par nœud ; choisissez le niveau de persistance le plus bas que la exigence de récupération autorise.
- Le cluster utilise exactement une connexion LAN privée, avec TLS disponible si vous l'activez lors de la configuration de l'instance, ne possède aucun point d'accès public, et ses identifiants sont figés à la création ; l'éviction par défaut
allkeys-lruest correcte pour un cache en lecture traversante.
Terminologie importante :
- Cache-aside : Un motif de lecture traversante où l'application lit le cache, bascule sur la base de données en cas de manqué, et alimente le cache avec le résultat ; les écritures sont dirigées vers la base de données et invalident ou mettent à jour la clé mise en cache.
- Write-through : Un motif où l'application écrit simultanément dans le cache et dans la base de données, gardant le cache autoritaire immédiatement après une écriture au prix de la latence d'écriture.
- Mode de persistance : Le paramètre In-Memory DB (Aucun, RDB, AOF, ou RDB_AOF) qui contrôle si les données survivent à un redémarrage et, via un multiplicateur fixe appliqué à la RAM, la quantité de Block Storage que le cluster provisionne.
- Politique d'éviction : La règle (par défaut
allkeys-lru) qui détermine quelles clés sont supprimées lorsqu'un nœud atteint sa limite de mémoire.
Lectures complémentaires
- Unité 5.3 : Bases de données relationnelles, pour la limite de réplique de lecture sans lecture que cette couche ferme
- Unité 4.3 : Élasticité et VM Auto Scaling, pour la précondition sans état que cette couche satisfait
- Unité 2.4 : Architecture des coûts et FinOps, pour l'économie de mise à l'échelle horizontale basée sur la cache par rapport à la mise à l'échelle verticale de la base de données