Guide pratique pour gérer la latence de queue
- 13 minutes
Nous avons déjà discuté de plusieurs techniques d’optimisation utilisées sur le cloud pour réduire la latence. Certaines des mesures que nous avons étudiées incluent la mise à l’échelle des ressources horizontalement ou verticalement et l’utilisation d’un équilibreur de charge pour acheminer les requêtes vers les ressources disponibles les plus proches. Cette page explique plus en détail pourquoi, dans un grand centre de données ou une application cloud, il est important de réduire la latence pour toutes les requêtes, et pas seulement d’optimiser le cas général. Nous allons étudier comment même quelques valeurs hors norme à latence élevée peuvent dégrader considérablement les performances observées d’un système volumineux. Cette page couvre également différentes techniques de création de services qui fournissent des réponses à faible latence prévisibles, même si les composants individuels ne garantissent pas cela. Il s’agit d’un problème particulièrement important pour les applications interactives où la latence souhaitée pour une interaction est inférieure à 100 ms.
Qu’est-ce que la latence de queue ?
La plupart des applications cloud sont de grands systèmes distribués qui s’appuient souvent sur la parallélisation pour réduire la latence. Une technique courante consiste à répartir une requête reçue par un nœud racine (par exemple, un serveur web frontal) vers de nombreux nœuds terminaux (serveurs de calcul de fond). L’amélioration des performances est pilotée par le parallélisme du calcul distribué, et par le fait que les coûts de déplacement de données extrêmement coûteux sont évités. Nous allons simplement déplacer le calcul vers l’emplacement où les données sont stockées. Bien sûr, chaque nœud feuille traite simultanément des centaines, voire des milliers, de requêtes parallèles.
Figure 7 : Latence due au scale-out
Prenons l’exemple de la recherche d’un film sur Netflix. Quand un utilisateur commence à taper dans la zone de recherche, il génère plusieurs événements parallèles à partir du serveur web racine. Au minimum, ces événements incluent les demandes suivantes :
- Pour le moteur de saisie semi-automatique, pour prédire réellement la recherche effectuée en fonction des tendances passées et du profil de l’utilisateur.
- Dans le moteur de correction, qui trouve des erreurs dans la requête typée en fonction d’un modèle de langage constamment adapté.
- Résultats de recherche individuels pour chacun des mots composant d’une requête à plusieurs mots, qui doivent être combinés en fonction du classement et de la pertinence des films.
- Post-traitement et filtrage supplémentaires des résultats pour répondre aux préférences de « recherche sécurisée » de l’utilisateur.
Ces exemples sont extrêmement courants. Une seule demande Facebook est connue pour contacter des milliers de serveurs memcached, tandis qu’une seule recherche Bing contacte souvent plus de dix mille serveurs d’index.
De toute évidence, le besoin de mise à l’échelle a conduit à une grande distribution ramifiée sur le back-end pour chaque requête individuelle traitée par le front-end. Pour les services qui sont censés être « réactifs » pour conserver leur base d’utilisateurs, les heuristiques montrent que les réponses sont attendues dans un délai de 100 ms. À mesure que le nombre de serveurs requis pour résoudre une requête augmente, le temps global dépend souvent de la réponse la plus performante d’un nœud feuille à un nœud racine. En supposant que tous les nœuds feuilles doivent terminer l’exécution avant qu’un résultat puisse être retourné, la latence globale doit toujours être supérieure à la latence du composant le plus lent.
Comme la plupart des processus stochastiques, le temps de réponse d’un nœud feuille unique peut être exprimé sous la forme d’une distribution. Des décennies d’expérience ont montré que dans le cas général, la plupart des demandes (>99%) d’un système cloud bien configuré s’exécuteront extrêmement rapidement. Mais souvent, il y a très peu d'anomalies sur un système s'exécutant extrêmement lentement.
Figure 8 : Exemple de latence de queue5
Considérez un système où tous les nœuds feuilles ont un temps de réponse moyen de 1 ms, mais il existe une probabilité de 1% que le temps de réponse est supérieur à 1 000 ms (une seconde). Si chaque requête est gérée par un seul nœud feuille, la probabilité que la requête prenne plus d’une seconde est également de 1%. Toutefois, à mesure que nous augmentons le nombre de nœuds à 100, la probabilité que la requête se termine dans un délai d’une seconde passe à 36,6%, ce qui signifie qu’il existe une probabilité de 63,4% que la durée de la requête soit déterminée par la fin (1%la plus faible) de la distribution de latence.
$(.99^{100})$
Si nous simulons cela pour divers cas, nous voyons que, à mesure que le nombre de serveurs augmente, l’impact d’une requête lente est plus prononcé (notez que le graphique ci-dessous augmente de façon monotonique). En outre, comme la probabilité de ces valeurs hors norme diminue de 1% à 0,01%, le système est sensiblement inférieur.
Figure 9 : Étude récente de la probabilité de temps de réponse qui montre les 50e, 95e et 99e centiles pour la latence des demandes4
Tout comme nous avons conçu nos applications pour qu’elles soient tolérantes aux pannes pour résoudre les problèmes de fiabilité des ressources, il doit être clair maintenant pourquoi il est important que les applications soient « tolérantes à la queue ». Pour pouvoir le faire, nous devons comprendre les sources de ces variations de performances longues et identifier les atténuations dans la mesure du possible et les solutions de contournement où elles ne sont pas possibles.
Variabilité dans le cloud : sources et atténuations
Pour résoudre la variabilité du temps de réponse qui entraîne ce problème de latence de queue, nous devons comprendre les causes de la variabilité du niveau de performance.1
- Utilisation de ressources partagées : de nombreuses machines virtuelles différentes (et applications au sein de ces machines virtuelles) font face à un pool partagé de ressources de calcul. Dans de rares cas, il est possible que cette contention entraîne une faible latence pour certaines requêtes. Pour les tâches critiques, il peut être judicieux d’utiliser des instances dédiées et d’exécuter régulièrement des benchmarks en cas d’inactivité, afin de s’assurer qu’il se comporte correctement.
- Démons et maintenance en arrière-plan : nous avons déjà parlé du besoin de processus en arrière-plan pour créer des points de contrôle, créer des sauvegardes, mettre à jour les journaux d’activité, collecter le garbage et gérer le nettoyage des ressources. Toutefois, elles peuvent dégrader les performances du système lors de l’exécution. Pour atténuer ce problème, il est important de synchroniser les interruptions en raison des threads de maintenance afin de réduire l’impact sur le flux de trafic. Cela entraîne la survenue de toutes les variantes dans une fenêtre courte et connue plutôt que aléatoirement au cours de la durée de vie de l’application.
- Mise en file d’attente : Le transfert en rafale des modèles d’arrivée de trafic est une autre source courante de variabilité.1 Cette variabilité est exacerbée si le système d’exploitation utilise un autre algorithme de planification que FIFO. Les systèmes Linux planifient souvent les threads dans un ordre non séquentiel afin d'optimiser le débit global et de maximiser l'utilisation du serveur. Des études ont révélé que l’utilisation de la planification FIFO dans le système d’exploitation réduit la latence de la queue au coût d’une réduction du débit global du système.
- Communication de type incast : Le modèle illustré à la figure 8 ci-dessus est appelé communication « tout-vers-tout ». Étant donné que la plupart des communications réseau sont sur TCP, cela entraîne des milliers de requêtes et réponses simultanées entre le serveur web frontal et tous les nœuds de traitement back-end. Il s’agit d’un modèle de communication en rafale extrêmement puissant, qui provoque souvent un certain genre de congestion appelé effondrement de la communication TCP incast.1, 2 La réponse soudaine intense de milliers de serveurs provoque l’abandon et la retransmission de nombreux paquets, ce qui entraîne en fin de compte une avalanche de trafic sur le réseau pour les paquets de données très petits. Les grands centres de données et les applications cloud doivent souvent utiliser des pilotes réseau personnalisés pour ajuster dynamiquement la fenêtre de réception TCP et le minuteur de retransmission. Les routeurs peuvent également être configurés pour supprimer le trafic qui dépasse un débit spécifique et réduire la taille de l’envoi.
- Gestion de l’alimentation et de la température : Enfin, la variabilité est un produit d’autres techniques de réduction des coûts telles que l’utilisation d’états inactifs ou d’une réduction de la fréquence du processeur. Un processeur peut souvent passer une quantité de temps significative à monter en puissance à partir d’un état inactif. La désactivation de ces optimisations des coûts entraîne une utilisation et des coûts plus élevés de l’énergie, mais une variabilité plus faible. Il s’agit moins d’un problème dans le cloud public, car les modèles tarifaires considèrent rarement les métriques d’utilisation interne des ressources du client.
Certaines expériences ont constaté que la variabilité de ces systèmes est beaucoup plus grave sur le cloud public, 3 généralement en raison d’une isolation des performances incorrectes des ressources virtuelles et du processeur partagé. Cela est aggravé si de nombreux travaux sensibles à la latence sont exécutés sur le même nœud physique que les travaux nécessitant beaucoup d’UC.
Vivre avec la variabilité : Solutions d’ingénierie
La plupart des sources de variabilité ci-dessus n’ont pas de solution infaillible. Par conséquent, au lieu d’essayer de résoudre toutes les sources qui gonflent la queue de latence, les applications cloud doivent être conçues pour être tolérantes à la queue. Cela, bien sûr, est similaire à la façon dont nous concevons des applications à tolérance de panne, car nous ne pouvons pas espérer corriger toutes les erreurs possibles. Voici quelques-unes des techniques courantes pour gérer cette variabilité :
- Résultats « assez bons » : Souvent, lorsque le système attend des résultats provenant de milliers de nœuds, l’importance d’un résultat unique peut être considérée comme assez faible. Par conséquent, de nombreuses applications peuvent choisir de répondre simplement aux utilisateurs avec des résultats qui arrivent dans une fenêtre de latence courte particulière et ignorent le reste.
- Canaries : une autre alternative souvent utilisée pour les chemins de code rares consiste à tester une demande sur un petit sous-ensemble de nœuds feuilles afin de tester s’il provoque un incident ou une défaillance qui peut avoir un impact sur l’ensemble du système. La requête de distribution ramifiée complète est générée uniquement si le contrôle de validité ne provoque pas de panne. Il est semblable à l’envoi d’un canari (oiseau) dans une mine de charbon pour tester s’il est sûr pour les humains.
- Probation induite par la latence et contrôles d’intégrité : Bien entendu, une grande partie des requêtes adressées à un système sont trop courantes pour pouvoir être testées à l’aide d’un contrôle de validité. De telles requêtes sont davantage susceptibles d’avoir une longue queue si l’un des nœuds terminaux fonctionne mal. Pour ce faire, le système doit surveiller régulièrement l’intégrité et la latence de chaque nœud feuille et ne pas acheminer les demandes vers les nœuds qui présentent des performances faibles (en raison de la maintenance ou des défaillances).
- QoS différentielle : des classes de service distinctes peuvent être créées pour les demandes interactives, ce qui leur permet de prendre la priorité dans n’importe quelle file d’attente. Les applications non sensibles à la latence peuvent tolérer des temps d’attente plus longs pour leurs opérations.
- Couverture des demandes : il s'agit d'une solution simple pour réduire l'impact de la variabilité en envoyant la même requête à plusieurs réplicas et en utilisant la réponse qui arrive en premier. Bien sûr, cela peut doubler ou tripler la quantité de ressources requises. Pour réduire le nombre de demandes couvertes de précaution, la deuxième demande peut être envoyée uniquement si la première réponse a été en attente depuis plus de 95e centile de la latence attendue pour cette demande. Cela entraîne une charge supplémentaire d’environ 5%, mais réduit considérablement la queue de latence (dans le cas typique indiqué dans la figure 9, où la latence du 95e centile est beaucoup plus faible que la latence du 99e centile).
- Exécution spéculative et réplication sélective : les tâches sur les nœuds particulièrement occupés peuvent être lancées spéculativement sur d’autres nœuds feuilles sous-utilisés. Cela est particulièrement efficace si une défaillance dans un nœud particulier entraîne sa surcharge.
- Solutions basées sur l’expérience utilisateur : Enfin, le délai peut être masqué intelligemment de l’utilisateur par le biais d’une interface utilisateur bien conçue qui réduit la sensation de retard rencontré par un utilisateur humain. Les techniques à suivre peuvent inclure l’utilisation d’animations, l’affichage de résultats précoces ou l’engagement de l’utilisateur en envoyant des messages pertinents.
En utilisant ces techniques, il est possible d’améliorer considérablement l’expérience des utilisateurs finaux d’une application cloud pour résoudre le problème particulier d’une longue queue.
références
- Li, J., Sharma, N. K., Ports, D. R., &Gribble, S. D. (2014). Tales of the Tail: Hardware, OS, and Application-Level Sources of Tail Latency Actes du Symposium ACM sur le cloud computing, ACM
- Wu, Haitao et Feng, Zhenqian et Guo, Chuanxiong et Zhang, Yongguang (2013). ICTCP: Incast Congestion Control for TCP in Data-Center Networks, IEEE/ACM Transactions on Networking (TON), IEEE Press
- Xu, Yunjing et Musgrave, Zachary et Noble, Brian et Bailey, Michael (2013). Bobtail : Éviter les longues queues dans le cloud, 10e conférence USENIX sur la conception et l’implémentation de systèmes réseau, association USENIX
- Dean, Jeffrey et Barroso, Luiz André (2013). The tail at scale, Communications of the ACM, ACM
- Tene, Gil (2014). [Compréhension de la latence - Quelques leçons et outils clés](https://www.infoq.com/presentations/latency-lessons-tools/, QCon London
Vérifier vos connaissances
Commentaires
Cette page a-t-elle été utile ?
No
Vous avez besoin d’aide pour cette rubrique ?
Vous souhaitez essayer d’utiliser Ask Learn pour clarifier ou vous guider dans cette rubrique ?