Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les infrastructures cloud telles que Le Stockage Azure fournissent une plateforme hautement disponible et durable pour l’hébergement de données et d’applications. Les développeurs d’applications basées sur le cloud doivent envisager soigneusement comment tirer parti de cette plateforme pour optimiser ces avantages pour leurs utilisateurs. Stockage Azure offre des options de géoredondance pour garantir une haute disponibilité, même lors d’une panne régionale. Les comptes de stockage configurés pour la réplication géoredondante sont répliqués de manière synchrone dans la région primaire, puis répliqués de manière asynchrone dans une région secondaire à des centaines de kilomètres.
Stockage Azure offre deux options pour la réplication géoredondante : le stockage géoredondant (GRS) et le stockage géoredondant interzone (GZRS). Pour utiliser les options de géoredondance du stockage Azure, assurez-vous que votre compte de stockage est configuré pour le stockage géoredondant avec accès en lecture (RA-GRS) ou le stockage géoredondant interzone d’accès en lecture (RA-GZRS). Si ce n’est pas le cas, vous pouvez en savoir plus sur la modification du type de réplication de votre compte de stockage.
Cet article explique comment concevoir une application qui continuera à fonctionner, même si elle est limitée, même en cas de panne importante dans la région primaire. Si la région primaire devient indisponible, votre application peut basculer en toute transparence pour effectuer des opérations de lecture sur la région secondaire jusqu’à ce que la région primaire soit réactive à nouveau.
Considérations relatives à la conception d’application
Vous pouvez concevoir votre application pour gérer les pannes temporaires ou les pannes significatives en lisant à partir de la région secondaire en cas de problème qui interfère avec la lecture à partir de la région primaire. Lorsque la région primaire est à nouveau disponible, votre application peut revenir à la lecture à partir de la région primaire.
Gardez à l’esprit ces considérations clés lors de la conception de votre application pour la disponibilité et la résilience à l’aide de RA-GRS ou RA-GZRS :
Une copie en lecture seule des données que vous stockez dans la région primaire est répliquée de manière asynchrone dans une région secondaire. Cette réplication asynchrone signifie que la copie en lecture seule dans la région secondaire est finalement cohérente avec les données de la région primaire. Le service de stockage détermine l’emplacement de la région secondaire.
Vous pouvez utiliser les bibliothèques clientes Stockage Azure pour effectuer des requêtes de lecture et de mise à jour sur le point de terminaison de la région primaire. Si la région primaire n’est pas disponible, vous pouvez rediriger automatiquement les demandes de lecture vers la région secondaire. Vous pouvez également configurer votre application pour envoyer des demandes de lecture directement à la région secondaire, le cas échéant, même lorsque la région primaire est disponible.
Si la région primaire devient indisponible, vous pouvez initier un transfert du compte. Lorsque vous basculez vers la région secondaire, les entrées DNS pointant vers la région primaire sont modifiées pour pointer vers la région secondaire. Une fois le basculement terminé, l’accès en écriture est restauré pour les comptes GRS et RA-GRS. Pour plus d’informations, consultez Récupération d’urgence et basculement de compte de stockage.
Utilisation de données éventuellement cohérentes
La solution proposée suppose qu’il est acceptable de retourner des données potentiellement obsolètes à l’application appelante. Étant donné que les données de la région secondaire sont finalement cohérentes, il est possible que la région primaire soit inaccessible avant qu’une mise à jour de la région secondaire ait terminé la réplication.
Par exemple, supposons que votre client envoie une mise à jour correctement, mais que la région primaire échoue avant la propagation de la mise à jour vers la région secondaire. Lorsque le client demande de lire les données, il reçoit les données obsolètes de la région secondaire au lieu des données mises à jour. Lors de la conception de votre application, vous devez décider si ce comportement est acceptable ou non. Si c’est le cas, vous devez également réfléchir à la façon de notifier l’utilisateur.
Plus loin dans cet article, vous allez en savoir plus sur la gestion des données cohérentes et sur la façon de vérifier la propriété Heure de la dernière synchronisation pour évaluer les différences entre les données dans les régions primaires et secondaires.
Gestion des services séparément ou tous ensemble
Bien que peu probable, il est possible pour un service (objets blob, files d’attente, tables ou fichiers) de devenir indisponible alors que les autres services sont toujours entièrement fonctionnels. Vous pouvez gérer les nouvelles tentatives pour chaque service séparément, ou vous pouvez gérer les nouvelles tentatives de manière générique pour tous les services de stockage ensemble.
Par exemple, si vous utilisez des files d’attente et des objets blob dans votre application, vous pouvez décider de placer du code distinct pour gérer les erreurs pouvant être retentées pour chaque service. Ainsi, une erreur du service blob affecte uniquement la partie de votre application qui traite des blobs, ce qui permet aux files d’attente de continuer à s’exécuter normalement. Toutefois, si vous décidez de gérer toutes les nouvelles tentatives de service de stockage ensemble, les demandes adressées aux services blob et de file d’attente seront affectées si l’un des services retourne une erreur renouvelable.
En fin de compte, cette décision dépend de la complexité de votre demande. Vous préférerez peut-être gérer les défaillances par service pour limiter l’impact des nouvelles tentatives. Vous pouvez également décider de rediriger les demandes de lecture pour tous les services de stockage vers la région secondaire lorsque vous détectez un problème avec n’importe quel service de stockage dans la région primaire.
Exécution de votre application en mode lecture seule
Pour préparer efficacement une panne dans la région primaire, votre application doit être en mesure de gérer les demandes de lecture ayant échoué et les demandes de mise à jour ayant échoué. Si la région primaire échoue, les demandes de lecture peuvent être redirigées vers la région secondaire. Toutefois, les demandes de mise à jour ne peuvent pas être redirigées, car les données répliquées dans la région secondaire sont en lecture seule. Pour cette raison, vous devez concevoir votre application pour pouvoir s’exécuter en mode lecture seule.
Par exemple, vous pouvez définir un indicateur vérifié avant que toutes les demandes de mise à jour ne soient envoyées au stockage Azure. Quand une demande de mise à jour est effectuée, vous pouvez ignorer la demande et renvoyer une réponse appropriée à l’utilisateur. Vous pouvez même choisir de désactiver certaines fonctionnalités jusqu’à ce que le problème soit résolu et avertir les utilisateurs que les fonctionnalités sont temporairement indisponibles.
Si vous décidez de gérer les erreurs pour chaque service séparément, vous devez également gérer la possibilité d’exécuter votre application en mode lecture seule par service. Par exemple, vous pouvez configurer des indicateurs en lecture seule pour chaque service. Vous pouvez ensuite activer ou désactiver les indicateurs dans le code, selon les besoins.
La possibilité d’exécuter votre application en mode lecture seule vous permet également de garantir des fonctionnalités limitées lors d’une mise à niveau majeure de l’application. Vous pouvez déclencher l’exécution de votre application en mode lecture seule et pointer vers le centre de données secondaire, en vous assurant que personne n’accède aux données dans la région primaire pendant que vous effectuez des mises à niveau.
Gestion des mises à jour en mode lecture seule
Il existe de nombreuses façons de gérer les demandes de mise à jour lors de l’exécution en mode lecture seule. Cette section se concentre sur quelques modèles généraux à prendre en compte.
Vous pouvez répondre à l’utilisateur et les informer que les demandes de mise à jour ne sont pas en cours de traitement. Par exemple, un système de gestion des contacts peut permettre aux utilisateurs d’accéder aux informations de contact, mais pas de mettre à jour.
Vous pouvez mettre en file d’attente vos mises à jour dans une autre région. Dans ce cas, vous devez écrire vos demandes de mise à jour en attente dans une file d’attente dans une autre région, puis traiter ces demandes une fois que le centre de données principal est à nouveau en ligne. Dans ce scénario, vous devez informer l’utilisateur que la demande de mise à jour est mise en file d’attente pour un traitement ultérieur.
Vous pouvez écrire vos mises à jour dans un compte de stockage dans une autre région. Lorsque la région primaire revient en ligne, vous pouvez fusionner ces mises à jour dans les données primaires, en fonction de la structure des données. Par exemple, si vous créez des fichiers distincts, dont le nom contient l’horodatage, vous pouvez recopier ces fichiers dans la région primaire. Cette solution peut s’appliquer aux charges de travail telles que la journalisation et les données IoT.
Gestion des nouvelles tentatives
Les applications qui communiquent avec les services exécutés dans le cloud doivent être sensibles aux événements non planifiés et aux erreurs qui peuvent se produire. Ces pannes peuvent être temporaires ou persistantes, allant d’une perte momentanée de connectivité à une panne importante en raison d’une catastrophe naturelle. Il est important de concevoir des applications cloud avec une gestion appropriée des nouvelles tentatives pour optimiser la disponibilité et améliorer la stabilité globale des applications.
Demandes de lecture
Si la région primaire devient indisponible, les demandes de lecture peuvent être redirigées vers le stockage secondaire. Comme indiqué précédemment, il doit être acceptable que votre application puisse lire des données obsolètes. La bibliothèque cliente Stockage Azure offre des options pour gérer les nouvelles tentatives et rediriger les demandes de lecture vers une région secondaire.
Dans cet exemple, la gestion des nouvelles tentatives pour le stockage Blob est configurée dans la classe et s’applique à l’objet BlobClientOptions
que nous créons à l’aide BlobServiceClient
de ces options de configuration. Cette configuration est une approche primaire puis secondaire , où les nouvelles tentatives de demande de lecture de la région primaire sont redirigées vers la région secondaire. Cette approche est optimale lorsque les défaillances dans la région primaire sont censées être temporaires.
string accountName = "<YOURSTORAGEACCOUNTNAME>";
Uri primaryAccountUri = new Uri($"https://{accountName}.blob.core.windows.net/");
Uri secondaryAccountUri = new Uri($"https://{accountName}-secondary.blob.core.windows.net/");
// Provide the client configuration options for connecting to Azure Blob storage
BlobClientOptions blobClientOptions = new BlobClientOptions()
{
Retry = {
// The delay between retry attempts for a fixed approach or the delay
// on which to base calculations for a backoff-based approach
Delay = TimeSpan.FromSeconds(2),
// The maximum number of retry attempts before giving up
MaxRetries = 5,
// The approach to use for calculating retry delays
Mode = RetryMode.Exponential,
// The maximum permissible delay between retry attempts
MaxDelay = TimeSpan.FromSeconds(10)
},
// If the GeoRedundantSecondaryUri property is set, the secondary Uri will be used for
// GET or HEAD requests during retries.
// If the status of the response from the secondary Uri is a 404, then subsequent retries
// for the request will not use the secondary Uri again, as this indicates that the resource
// may not have propagated there yet.
// Otherwise, subsequent retries will alternate back and forth between primary and secondary Uri.
GeoRedundantSecondaryUri = secondaryAccountUri
};
// Create a BlobServiceClient object using the configuration options above
BlobServiceClient blobServiceClient = new BlobServiceClient(primaryAccountUri, new DefaultAzureCredential(), blobClientOptions);
Si vous déterminez que la région primaire est susceptible d’être indisponible pendant une longue période, vous pouvez configurer toutes les demandes de lecture pour qu’elles pointent vers la région secondaire. Cette configuration est une approche secondaire uniquement . Comme indiqué précédemment, vous aurez besoin d’une stratégie pour gérer les demandes de mise à jour pendant ce temps et un moyen d’informer les utilisateurs que seules les demandes de lecture sont traitées. Dans cet exemple, nous créons une nouvelle instance BlobServiceClient
qui utilise le point de terminaison de la région secondaire.
string accountName = "<YOURSTORAGEACCOUNTNAME>";
Uri primaryAccountUri = new Uri($"https://{accountName}.blob.core.windows.net/");
Uri secondaryAccountUri = new Uri($"https://{accountName}-secondary.blob.core.windows.net/");
// Create a BlobServiceClient object pointed at the secondary Uri
// Use blobServiceClientSecondary only when issuing read requests, as secondary storage is read-only
BlobServiceClient blobServiceClientSecondary = new BlobServiceClient(secondaryAccountUri, new DefaultAzureCredential(), blobClientOptions);
Savoir quand basculer vers le mode lecture seule et les demandes secondaires uniquement fait partie d’un modèle de conception architecturale appelé modèle Disjoncteur, qui sera abordé dans une section ultérieure.
Demandes de mise à jour
Les demandes de mise à jour ne peuvent pas être redirigées vers le stockage secondaire, qui est en lecture seule. Comme décrit précédemment, votre application doit pouvoir gérer les demandes de mise à jour lorsque la région primaire n’est pas disponible.
Le modèle Disjoncteur peut également être appliqué aux demandes de mise à jour. Pour gérer les erreurs de demande de mise à jour, vous pouvez définir un seuil dans le code, par exemple 10 échecs consécutifs, et suivre le nombre d’échecs pour les demandes adressées à la région primaire. Une fois le seuil atteint, vous pouvez basculer l’application en mode lecture seule afin que les demandes de mise à jour vers la région primaire ne soient plus émises.
Comment implémenter le schéma Disjoncteur
La gestion des défaillances pouvant prendre un certain temps pour être surmontées fait partie d'un modèle de conception architecturale appelé le modèle Circuit Breaker. Une implémentation appropriée de ce modèle peut empêcher une application de tenter à plusieurs reprises d’exécuter une opération susceptible d’échouer, améliorant ainsi la stabilité et la résilience de l’application.
L’un des aspects du modèle Disjoncteur est d’identifier à quel moment il existe un problème en cours avec un point de terminaison principal. Pour effectuer cette évaluation, vous pouvez surveiller la fréquence à laquelle le client rencontre des erreurs réessayables. Étant donné que chaque scénario est différent, vous devez déterminer un seuil approprié à utiliser pour la décision de basculer vers le point de terminaison secondaire et exécuter l’application en mode lecture seule.
Par exemple, vous pouvez décider d’effectuer le basculement s'il y a 10 échecs consécutifs dans la région primaire. Vous pouvez suivre cette opération en conservant le nombre des échecs dans le code. En cas de réussite avant d’atteindre le seuil, remettez le compteur à zéro. Si le nombre atteint le seuil, changez l’application pour utiliser la région secondaire pour les demandes de lecture.
En guise d’approche alternative, vous pouvez décider d’implémenter un composant de supervision personnalisé dans votre application. Ce composant pourrait continuellement pinger votre point de terminaison principal du stockage avec des demandes de lecture triviales (comme un petit blob) pour vérifier son état de santé. Cette approche prendrait certaines ressources, mais pas un montant significatif. Lorsqu’un problème est détecté qui atteint votre seuil, vous basculez vers les demandes de lecture secondaires uniquement et le mode lecture seule. Pour ce scénario, lorsque vous effectuez un test ping sur le point de terminaison de stockage principal, vous pouvez revenir à la région primaire et continuer à autoriser les mises à jour.
Le seuil d'erreur utilisé pour déterminer quand effectuer la transition peut varier d'un service à l'autre au sein de votre application, vous devriez donc envisager de les rendre des paramètres configurables.
Une autre considération est la façon de gérer plusieurs instances d’une application et ce qu’il faut faire lorsque vous détectez des erreurs retentantes dans chaque instance. Par exemple, vous pouvez avoir 20 machines virtuelles en cours d’exécution avec la même application chargée. Gérez-vous chaque instance séparément ? Si une instance commence à rencontrer des problèmes, voulez-vous limiter la réponse à cette seule instance ? Ou voulez-vous que toutes les instances répondent de la même façon quand une instance a un problème ? La gestion des instances séparément est beaucoup plus simple que d’essayer de coordonner la réponse entre elles, mais votre approche dépend de l’architecture de votre application.
Gestion des données finalement cohérentes
Le stockage géoredondant fonctionne en répliquant les transactions du serveur principal vers la région secondaire. Le processus de réplication garantit que les données de la région secondaire sont finalement cohérentes. Cela signifie que toutes les transactions de la région primaire apparaissent finalement dans la région secondaire, mais qu’il peut y avoir un décalage avant qu’elles n’apparaissent. Il n’existe pas non plus de garantie que les transactions arrivent dans la région secondaire dans le même ordre qu’elles ont été appliquées à l’origine dans la région primaire. Si vos transactions arrivent dans la région secondaire dans un ordre incorrect, vous pouvez considérer vos données dans la région secondaire comme étant dans un état incohérent jusqu'à ce que le service se synchronise.
L’exemple suivant pour le stockage Table Azure montre ce qui peut se produire lorsque vous mettez à jour les détails d’un employé pour les rendre membres du rôle d’administrateur. Pour cet exemple, vous devez mettre à jour l’entité employé et mettre à jour une entité de rôle d’administrateur avec le nombre total d’administrateurs. Notez comment les mises à jour sont appliquées hors ordre dans la région secondaire.
Heure | Transaction | Réplication | heure de la dernière synchronisation | Résultat |
---|---|---|---|---|
T0 | Transaction A : Insérer un employé entité dans le groupe principal |
Transaction A insérée dans le serveur principal, n'a pas encore été répliqué. |
||
T1 | Transaction A répliquée dans secondaire |
T1 | Transaction A répliquée sur le site secondaire. Heure de la dernière synchronisation mise à jour. |
|
T2 | Transaction B : Mise à jour entité d'employé dans le primaire |
T1 | Transaction B écrite dans la base de données primaire, n'a pas encore été répliqué. |
|
T3 | Transaction C : Mettre à jour administrateur entité de rôle dans primaire |
T1 | Transaction C écrite dans le principal. n'a pas encore été répliqué. |
|
T4 | Transaction C répliquée dans secondaire |
T1 | Transaction C répliquée sur le serveur secondaire. LastSyncTime non mis à jour, car la transaction B n’a pas encore été répliquée. |
|
T5 | Lire les entités à partir de secondaire |
T1 | Vous obtenez la valeur obsolète pour l’employé entité, car la transaction B n’a pas encore eu lieu pas encore répliqué. Vous obtenez la nouvelle valeur pour entité de rôle d’administrateur, car C a Répliqué. L’heure de la dernière synchronisation n’a pas encore été mise à jour. Elle a été mise à jour parce que la transaction B n'a pas répliqué. On peut le constater L’entité de rôle d’administrateur est non cohérente. car la date/heure de l’entité est postérieure Heure de la dernière synchronisation. |
|
T6 | Transaction B répliquée dans secondaire |
T6 |
T6 : toutes les transactions par le biais de C ont A été répliqué, Heure de la dernière synchronisation est mis à jour. |
Dans cet exemple, supposons que le client passe à la lecture à partir de la région secondaire à T5. Il peut lire avec succès l’entité de rôle d’administrateur actuellement, mais l’entité contient une valeur pour le nombre d’administrateurs qui n'est pas cohérente avec le nombre d’entités d’employés marquées comme administrateurs dans la région secondaire actuellement. Votre client peut afficher cette valeur, avec le risque que les informations ne sont pas cohérentes. Le client peut également tenter de déterminer que le rôle d’administrateur est dans un état potentiellement incohérent, car les mises à jour se sont produites hors de commande, puis informer l’utilisateur de ce fait.
Pour déterminer si un compte de stockage a des données potentiellement incohérentes, le client peut vérifier la valeur de la propriété Heure de la dernière synchronisation . L’heure de la dernière synchronisation vous indique l’heure à laquelle les données de la région secondaire étaient cohérentes pour la dernière fois et lorsque le service avait appliqué toutes les transactions antérieures à ce point dans le temps. Dans l’exemple ci-dessus, une fois que le service insère l’entité employé dans la région secondaire, l’heure de la dernière synchronisation est définie sur T1. Il reste au niveau T1 jusqu’à ce que le service mette à jour l’entité employé dans la région secondaire lorsqu’elle est définie sur T6. Si le client récupère l’heure de la dernière synchronisation lorsqu’il lit l’entité au niveau T5, il peut le comparer à l’horodatage sur l’entité. Si l’horodatage sur l’entité est supérieur à l’heure de la dernière synchronisation, l’entité est dans un état potentiellement incohérent et vous pouvez effectuer l’action appropriée. L’utilisation de ce champ nécessite que vous sachiez quand la dernière mise à jour vers le serveur principal a été terminée.
Pour savoir comment vérifier l’heure de la dernière synchronisation, consultez La propriété Vérifier l’heure de la dernière synchronisation pour un compte de stockage.
Essai
Il est important de tester que votre application se comporte comme prévu lorsqu’elle rencontre des erreurs retentables. Par exemple, vous devez tester que l’application bascule vers la région secondaire lorsqu’elle détecte un problème, puis retourne lorsque la région primaire devient à nouveau disponible. Pour tester correctement ce comportement, vous avez besoin d’un moyen de simuler des erreurs retentantes et de contrôler la fréquence à laquelle elles se produisent.
L’une des options consiste à utiliser Fiddler pour intercepter et modifier les réponses HTTP dans un script. Ce script peut identifier les réponses provenant de votre point de terminaison principal et modifier le code d’état HTTP en un que la bibliothèque cliente de stockage reconnaît comme une erreur retentante. Cet extrait de code montre un exemple simple d’un script Fiddler qui intercepte les réponses aux demandes de lecture sur la table employeedata pour retourner un état 502 :
static function OnBeforeResponse(oSession: Session) {
...
if ((oSession.hostname == "\[YOURSTORAGEACCOUNTNAME\].table.core.windows.net")
&& (oSession.PathAndQuery.StartsWith("/employeedata?$filter"))) {
oSession.responseCode = 502;
}
}
Vous pouvez étendre cet exemple pour intercepter une plus grande gamme de requêtes et modifier uniquement le responseCode sur certains d’entre eux pour mieux simuler un scénario réel. Pour plus d’informations sur la personnalisation des scripts Fiddler, consultez Modification d’une demande ou d’une réponse dans la documentation Fiddler.
Si vous avez configuré des seuils configurables pour basculer votre application en lecture seule, il sera plus facile de tester le comportement avec des volumes de transactions hors production.
Étapes suivantes
Pour un exemple complet montrant comment alterner entre les endpoints principaux et secondaires, consultez Exemples Azure : utilisation du pattern de circuit breaker avec le stockage RA-GRS.