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
Créer des applications robustes sur Neptune implique souvent de se préparer aux imprévus, notamment en ce qui concerne la gestion des erreurs renvoyées par la base de données. L'une des réponses les plus courantes aux exceptions côté serveur consiste à recommencer l'opération qui a échoué. Bien que la logique des nouvelles tentatives soit essentielle pour les systèmes résilients, vous devez savoir 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 des nouvelles tentatives est un composant essentiel de toute application distribuée. Des problèmes transitoires tels que l'instabilité du réseau, des contraintes temporaires de ressources ou des conflits de modifications 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 nouvelle tentative solide reconnaît la réalité des environnements imparfaits dans les systèmes distribués, garantissant ainsi une fiabilité et une continuité accrues tout en nécessitant moins d'interventions manuelles.
Les risques de nouveaux essais sans discernement
Réessayer chaque erreur par défaut peut avoir plusieurs conséquences imprévues :
-
Contentieux accru : lorsque des opérations qui échouent en raison d'une forte simultanéité sont réessayées à plusieurs reprises, le conflit global peut s'aggraver. Cela peut entraîner un cycle de transactions échouées et une dégradation des performances.
-
Épuisement des ressources : les nouvelles tentatives indiscriminées peuvent consommer des ressources système supplémentaires, à la fois du côté client et du côté serveur. Cela peut potentiellement entraîner un ralentissement ou même une dégradation du service.
-
Latence accrue pour les clients — Les nouvelles 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 pratique en matière de nouvelles tentatives
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 points à prendre en compte pour orienter votre approche :
-
Identifiez les erreurs susceptibles d'être réessayées — 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 devraient pas déclencher une nouvelle tentative. Neptune fournit des codes d'erreur et des recommandations générales pour savoir quelles erreurs peuvent être réessayées 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 d'arrêt exponentiel afin d'augmenter progressivement le temps d'attente entre les nouvelles 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 : si vous effectuez la première tentative trop rapidement, vous risquez de générer la même erreur si le serveur n'a pas eu suffisamment de temps pour libérer les ressources nécessaires à la réussite de la requête. Une pause plus longue dans les bonnes situations pourrait réduire les demandes inutiles et la pression du serveur.
-
Ajoutez de la nervosité à l'arrêt — Bien que l'arrêt exponentiel soit efficace, il peut tout de même entraîner des tempêtes de nouvelles tentatives synchronisées si de nombreux clients échouent en même temps, puis réessayent ensemble. L'ajout de jitter, une petite variation aléatoire du délai d'attente, permet d'étaler les nouvelles tentatives, réduisant ainsi le risque que tous les clients réessayent simultanément et provoquant un nouveau pic de charge.
-
Limiter le nombre de 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 nouvelles tentatives si nécessaire. Si vous constatez un nombre élevé de tentatives pour une opération donnée, demandez-vous si l'opération peut être optimisée ou sérialisée.
Pour une discussion plus approfondie sur le backoff exponentiel et la gigue en tant que modèle général de conception du cloud, voir Réessayer avec un backoff dans Prescriptive Guidance. AWS
Exemples de scénarios
La bonne stratégie de nouvelle tentative 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 suivent à titre de contexte supplémentaire.
|
Scénario |
Récupérable ? |
Backoff et nervosité |
Pause initiale |
Limite de nouvelles tentatives |
Surveiller et régler |
|---|---|---|---|---|---|
|
CME occasionnel sur de courtes requêtes |
Oui |
Temps de recul court, ajoute de la nervosité |
Courte (par exemple, 100 ms) |
Élevée |
Surveillez la hausse des taux CME |
|
CME fréquent sur les requêtes Longer-Running |
Oui |
Temps de recul plus long, ajout de gigue |
Plus long (par exemple, 2 s) |
Modérée |
Étudiez et réduisez les conflits |
|
Limites de mémoire pour les requêtes coûteuses |
Oui |
Longue période de recul |
Longue (5 à 10 secondes, par exemple) |
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, ajout de gigue |
Modéré (par exemple, 1s) |
Faible à modérée |
Évaluation de la charge du serveur et de 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é. Effectuez une courte pause initiale (par exemple, 100 millisecondes) avant la première tentative. Ce temps permet à n'importe quel verrou bref de s'effacer. Combinez cela à un bref retard exponentiel et à de la gigue pour éviter les nouvelles tentatives synchronisées. Le coût des nouvelles tentatives étant faible, une limite de nouvelles tentatives plus élevée est raisonnable. Surveillez tout de même le taux 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 voit des CME fréquents sur des requêtes de longue durée, cela suggère un conflit plus grave. Dans ce cas, commencez par une pause initiale plus longue (par exemple, 2 secondes), pour donner à la requête en cours contenant le verrou suffisamment de temps pour se terminer. Utilisez une temporisation exponentielle plus longue et ajoutez de la gigue. Limitez le nombre de nouvelles tentatives pour éviter des retards et une utilisation des ressources excessifs. Si le conflit persiste, examinez votre charge de travail pour détecter les modèles et envisagez de sérialiser les mises à jour ou de réduire la simultanéité pour remédier à 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 lors d'une requête gourmande en ressources connue, les nouvelles tentatives peuvent être judicieuses, 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 limite de nouvelles tentatives faible, 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 inciter à revoir la complexité des requêtes et l'utilisation des ressources.
Scénario 4 : délai d'attente 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'expiration était dû à un pic temporaire de charge du serveur ou à l'état du réseau. Commencez par une pause initiale modérée (par exemple, 1 seconde) pour permettre au système de se rétablir. Appliquez un backoff 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 tendances : si les délais d'attente deviennent fréquents, déterminez si la requête doit être optimisée ou si le cluster Neptune est sous-provisionné.
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 requêtes 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, de ressources sous-provisionnées ou d'une tempête de nouvelles tentatives. La surveillance de cette métrique vous aide à identifier les cas où votre stratégie de nouvelle tentative est à l'origine ou à l'aggravation des problèmes liés à la mise en file d'attente, et peut vous inciter à ajuster votre approche avant que les échecs ne s'aggravent.
Autres CloudWatch indicateurs
D'autres métriques de NeptuneCPUUtilization, telles queTotalRequestsPerSecond, et la latence des requêtes, fournissent un contexte supplémentaire. Par exemple, un processeur élevé et des I/O files d'attente de plus en plus longues peuvent 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.
API Neptune Status et Query
L'API Neptune Status pour Gremlin et ses API analogues pour et SPARQL fournissent une vue en temps réel des requêtes acceptées OpenCypher et 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.
En combinant ces outils de surveillance, vous pouvez :
-
Détectez quand les nouvelles tentatives contribuent à la mise en file d'attente et à la dégradation des performances.
-
Déterminez à quel moment vous devez dimensionner votre cluster Neptune ou optimiser les requêtes.
-
Vérifiez que votre stratégie de nouvelle tentative permet de résoudre les échecs transitoires sans masquer des problèmes plus profonds.
-
Recevez des alertes précoces en cas de conflit émergent ou d'épuisement des ressources.
La surveillance et les alertes proactives sont essentielles pour maintenir un déploiement Neptune en bonne santé, en particulier lorsque la simultanéité et la complexité de votre application augmentent.