Gestion des exceptions et nouvelles tentatives - 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.

Gestion des exceptions et nouvelles tentatives

Pour créer des applications robustes sur Neptune, il faut souvent se préparer aux imprévus, notamment lorsqu'il s'agit de gérer les erreurs renvoyées par la base de données. L'une des réponses les plus courantes aux exceptions côté serveur consiste à réessayer l'opération qui a échoué. Bien que la logique des nouvelles tentatives soit essentielle à la résilience des systèmes, vous devez reconnaître que toutes les erreurs ne doivent pas être traitées de la même manière. Plutôt que de vous fier à des comportements de nouvelle tentative génériques, une approche réfléchie peut vous aider à créer des applications plus fiables et plus efficaces.

Pourquoi la logique des nouvelles tentatives est importante

La logique de nouvelle tentative est un élément essentiel de toute application distribuée. Des problèmes transitoires tels que l'instabilité du réseau, des contraintes de ressources temporaires ou des conflits de modification simultanés peuvent entraîner l'échec des opérations. Dans de nombreux cas, ces échecs n'indiquent pas un problème permanent et peuvent être résolus en attendant et en réessayant. La mise en œuvre d'une stratégie de relance solide tient compte de la réalité des environnements imparfaits dans les systèmes distribués, garantissant ainsi une fiabilité et une continuité accrues avec moins d'interventions manuelles.

Les risques de nouvelles tentatives indiscriminées

Réessayer chaque erreur par défaut peut avoir plusieurs conséquences imprévues :

  • Contentions accrues : lorsque des opérations qui échouent en raison d'une forte simultanéité sont réessayées à plusieurs reprises, le contentieux général peut s'aggraver. Cela peut entraîner un cycle d'échecs de transactions et de dégradation des performances.

  • Épuisement des ressources — Les tentatives indiscriminées peuvent consommer des ressources système supplémentaires, tant du côté du client que du côté du serveur. Cela peut potentiellement entraîner un ralentissement ou même une dégradation du service.

  • Latence accrue pour les clients — Des tentatives excessives peuvent entraîner des retards importants pour les applications clientes, en particulier si chaque nouvelle tentative implique des périodes d'attente. Cela peut avoir un impact négatif sur l'expérience utilisateur et les processus en aval.

Élaboration d'une stratégie de réessai pratique

Pour créer une application résiliente et efficace, développez une stratégie de nouvelle tentative adaptée aux conditions d'erreur spécifiques que votre application peut rencontrer. Voici quelques éléments à prendre en compte pour orienter votre approche :

  • Identifiez les erreurs réessayables : toutes les exceptions ne doivent pas être réessayées. Par exemple, les erreurs de syntaxe, les échecs d'authentification ou les requêtes non valides ne doivent pas déclencher une nouvelle tentative. Neptune fournit des codes d'erreur et des recommandations générales pour lesquels vous pouvez réessayer en toute sécurité, mais vous devez implémenter la logique adaptée à votre cas d'utilisation.

  • Implémenter un délai d'attente exponentiel : pour les erreurs transitoires, utilisez une stratégie de temporisation exponentielle afin d'augmenter progressivement le temps d'attente entre les tentatives. Cela permet d'atténuer les conflits et de réduire le risque de défaillances en cascade.

  • Tenez compte de la durée de la pause initiale : une première tentative trop rapide peut se terminer par la même erreur si le serveur n'a pas eu le temps de libérer les ressources dont la requête a besoin pour réussir. Une pause plus longue dans les bonnes situations pourrait réduire le gaspillage de demandes et la pression du serveur.

  • Ajoutez de la nervosité au temps perdu : même si le ralentissement exponentiel est efficace, il peut tout de même entraîner des tempêtes de tentatives synchronisées si de nombreux clients échouent en même temps puis réessayent ensemble. L'ajout de gigter, une petite variation aléatoire du délai d'attente, permet d'étaler les tentatives de relance, réduisant ainsi le risque que tous les clients réessayent simultanément et provoquent un nouveau pic de charge.

  • Limiter les tentatives : définissez un nombre maximum raisonnable de tentatives pour éviter les boucles infinies et l'épuisement des ressources.

  • Surveiller et ajuster — Surveillez en permanence le taux d'erreur de votre application et ajustez votre stratégie de réessai en fonction des besoins. Si vous remarquez un nombre élevé de tentatives pour une opération donnée, déterminez si l'opération peut être optimisée ou sérialisée.

Exemples de scénarios

La bonne stratégie de relance dépend de la nature de l'échec, de la charge de travail et des modèles d'erreur que vous observez. Le tableau suivant résume certains scénarios d'échec courants et explique comment les considérations relatives à la stratégie de nouvelle tentative s'appliquent à chacun d'entre eux. Les paragraphes explicatifs suivants fournissent un contexte supplémentaire.

Scénario

Récupérable ?

Retard et instabilité

Pause initiale

Limite de tentatives

Surveiller et régler

CME occasionnel sur des requêtes courtes

Oui

Retournez rapidement, ajoutez de la nervosité

Courte (par exemple, 100 ms)

Élevé

Surveillez la hausse des taux CME

CME fréquent pour les requêtes de longue durée

Oui

Temps d'arrêt plus long, augmentation de la nervosité

Plus long (par exemple, 2 secondes)

Modérée

Étudier et réduire les litiges

Limites de mémoire pour les requêtes coûteuses

Oui

Longue pause

Longue (par exemple, 5 à 10 secondes)

Faible

Optimisation de la requête, alerte en cas de persistance

Délai d'attente pour les requêtes modérées

Peut-être

Atténuation modérée, augmentation de la nervosité

Modéré (par exemple, 1 s)

Faible à modérée

Évaluer la charge du serveur et la conception des requêtes

Scénario 1 : CME occasionnel sur de courtes requêtes

Pour une charge de travail qui ConcurrentModificationException apparaît rarement lors de mises à jour courtes et simples, ces erreurs sont généralement transitoires et peuvent être réessayées en toute sécurité. Faites une courte pause initiale (par exemple, 100 millisecondes) avant la première tentative. Cette durée permet à tout bref verrou de s'effacer. Ajoutez à cela un court recul et une instabilité exponentiels pour éviter les nouvelles tentatives synchronisées. Le coût d'une nouvelle tentative étant faible, une limite de nouvelles tentatives plus élevée est raisonnable. Néanmoins, surveillez le taux de CME pour détecter toute tendance à une augmentation de la contention dans vos données.

Scénario 2 : CME fréquent sur des requêtes de longue durée

Si votre application reçoit des requêtes fréquentes CMEs ou de longue durée, cela suggère une contention plus grave. Dans ce cas, commencez par une pause initiale plus longue (par exemple, 2 secondes), pour que la requête en cours contenant le verrou ait suffisamment de temps pour se terminer. Utilisez un recul exponentiel plus long et ajoutez de l'instabilité. Limitez le nombre de tentatives afin d'éviter les retards excessifs et l'utilisation excessive des ressources. Si le conflit persiste, examinez votre charge de travail pour détecter des tendances et envisagez de sérialiser les mises à jour ou de réduire la simultanéité pour en traiter la cause première.

Scénario 3 : limites de mémoire pour les requêtes coûteuses

Lorsque des erreurs liées à la mémoire se produisent au cours d'une requête connue nécessitant beaucoup de ressources, il peut être judicieux de réessayer, mais uniquement après une longue pause initiale (par exemple, 5 à 10 secondes ou plus) pour permettre au serveur de libérer des ressources. Utilisez une stratégie d'attente prolongée et définissez une faible limite de tentatives, car il est peu probable que les échecs répétés soient résolus sans modification de la requête ou de la charge de travail. Les erreurs persistantes devraient déclencher des alertes et entraîner un examen de la complexité des requêtes et de l'utilisation des ressources.

Scénario 4 : délai d'expiration pour les requêtes modérées

Un délai d'attente pour une requête modérément coûteuse est un cas plus ambigu. Parfois, une nouvelle tentative peut réussir si le délai d'attente est dû à un pic temporaire de charge du serveur ou aux conditions du réseau. Commencez par une pause initiale modérée (1 seconde, par exemple) pour donner au système une chance de récupérer. Appliquez un ralentissement modéré et ajoutez de la gigue pour éviter les nouvelles tentatives synchronisées. Maintenez la limite de tentatives faible à modérée, car des délais d'attente répétés peuvent indiquer un problème plus grave lié à la requête ou à la capacité du serveur. Surveillez les modèles : si les délais deviennent fréquents, déterminez si la requête doit être optimisée ou si le cluster Neptune est sous-approvisionné.

Surveillance et observabilité

La surveillance est un élément essentiel de toute stratégie de nouvelle tentative. Une observabilité efficace vous aide à comprendre dans quelle mesure votre logique de nouvelle tentative fonctionne et fournit des signaux précoces lorsqu'un élément de votre charge de travail ou de la configuration de votre cluster nécessite une attention particulière.

MainRequestQueuePendingRequests

Cette CloudWatch métrique permet de suivre le nombre de demandes en attente dans la file d'entrée de Neptune. Une valeur croissante indique que les requêtes sont sauvegardées, ce qui peut être le signe d'un contentieux excessif, d'un sous-provisionnement des ressources ou d'une tempête de nouvelles tentatives. La surveillance de cette métrique vous permet de déterminer si votre stratégie de nouvelle tentative est à l'origine ou aggrave les problèmes de file d'attente, et peut vous inviter à ajuster votre approche avant que les échecs ne se multiplient.

Autres CloudWatch mesures

D'autres indicateurs NeptuneCPUUtilization, tels que, et la latence des requêtesTotalRequestsPerSecond, fournissent un contexte supplémentaire. Par exemple, un processeur élevé I/O associé à des files d'attente de plus en plus longues peut indiquer que votre cluster est surchargé ou que les requêtes sont trop volumineuses ou trop fréquentes. CloudWatch des alarmes peuvent être définies sur ces métriques pour vous avertir d'un comportement anormal et vous aider à corréler les pics d'erreurs ou de nouvelles tentatives avec les contraintes de ressources sous-jacentes.

État et requête de Neptune APIs

L'API Neptune Status pour G705 et son équivalent pour et SPARQL fournissent une vue en temps réel des requêtes acceptées OpenCypheret exécutées sur le cluster, ce qui est utile pour diagnostiquer les goulots d'étranglement ou comprendre l'impact de la logique de nouvelle tentative en temps réel. APIs

En combinant ces outils de surveillance, vous pouvez :

  • Détectez les cas où de nouvelles tentatives contribuent à la mise en file d'attente et à la dégradation des performances.

  • Identifiez à quel moment il convient de dimensionner votre cluster Neptune ou d'optimiser les requêtes.

  • Vérifiez que votre stratégie de nouvelle tentative résout les échecs transitoires sans masquer les problèmes plus graves.

  • Recevez des alertes précoces en cas de conflits émergents ou d'épuisement des ressources.

La surveillance et les alertes proactives sont essentielles au bon déroulement du déploiement de Neptune, en particulier à mesure que la simultanéité et la complexité de votre application augmentent.