Pub/Sub est un service de messagerie asynchrone conçu pour être extrêmement fiable et évolutif. Le service repose sur un composant d'infrastructure de base de Google sur lequel s'appuient également de nombreux produits Google depuis plus de 10 ans. Les produits Google tels que Google Ads, la recherche et Gmail se servent de cette infrastructure pour envoyer plus de 500 millions de messages par seconde, représentant un débit total de plus de 1 To/s de données. Cet article décrit les principales caractéristiques de conception permettant à Pub/Sub de fournir un service fiable à une telle échelle.
Évaluer les performances d'un service de messagerie
Un service de messagerie tel que Pub/Sub peut être jugé sur ses performances suivant trois aspects : l'évolutivité, la disponibilité et la latence. Ces trois critères sont souvent contradictoires et nécessitent des compromis sur l'un pour améliorer les deux autres.
Les termes "évolutivité", "disponibilité" et "latence" peuvent désigner différentes propriétés d'un système. Par conséquent, les sections suivantes décrivent leur définition dans le contexte de Pub/Sub.
Évolutivité
Un service évolutif doit pouvoir gérer les augmentations de charge sans dégradation notable de la latence ou de la disponibilité. La "charge" peut faire référence à différentes dimensions d'utilisation dans Pub/Sub :
Le nombre de sujets
Le nombre d'éditeurs
Le nombre d'abonnements
Le nombre d'abonnés
Le nombre de messages
La taille des messages
Le débit (ou taux) de messages publiés ou consommés
Le volume en attente sur un abonnement donné
Disponibilité
Dans un système distribué, les types de problèmes rencontrés et leur gravité peuvent varier considérablement. La disponibilité d'un système est évaluée suivant sa capacité à traiter différents types de problèmes et à gérer une panne de manière optimale et transparente pour les utilisateurs finaux. Des défaillances peuvent survenir au niveau du matériel (par exemple, des pannes de disques durs ou des problèmes de connectivité réseau), au niveau logiciel, ou à cause de la charge. Une défaillance due à la charge peut survenir lorsqu'une augmentation soudaine du trafic au sein du service (ou dans d'autres composants logiciels s'exécutant sur le même matériel, ou dans des dépendances logicielles) entraîne une pénurie de ressources. La disponibilité peut également se dégrader du fait d'une erreur humaine, par exemple lors de la création ou du déploiement de logiciels ou de configurations.
Latence
La latence est une mesure temporelle de la performance d'un système. Un service cherche généralement à minimiser la latence autant que possible. Pour Pub/Sub, les deux mesures de latence principales sont les suivantes :
La durée nécessaire pour accuser réception d'un message publié
La durée nécessaire pour distribuer un message publié à un abonné
Architecture Pub/Sub de base
Dans cette section, nous expliquons la conception de Pub/Sub pour montrer comment le service atteint son évolutivité et sa faible latence tout en conservant sa disponibilité. Le système est conçu pour être évolutif horizontalement, c'est-à-dire qu'il peut gérer une hausse du nombre de sujets, d'abonnements ou de messages en augmentant le nombre d'instances de serveurs en cours d'exécution.
Les serveurs Pub/Sub fonctionnent dans toutes les régions Google Cloud réparties dans le monde entier. Ainsi, le service offre un accès rapide et mondial aux données, tout en permettant aux utilisateurs de contrôler l'emplacement de stockage des messages. Cloud Pub/Sub offre un accès mondial aux données de cet éditeur et les clients abonnés ignorent l'emplacement des serveurs auxquels ils se connectent ou la manière dont ces services acheminent les données.
Les mécanismes d'équilibrage de charge de Pub/Sub acheminent le trafic de l'éditeur vers le centre de données Google Cloud le plus proche autorisant le stockage de données, tel que défini dans la section Restriction d'emplacement des ressources de la console IAM et administration. Ainsi, les éditeurs de plusieurs régions peuvent publier des messages sur un seul sujet avec une faible latence. Tous les messages individuels sont stockés dans une seule région. Cependant, un sujet peut contenir des messages stockés dans plusieurs régions. Lorsqu'un client abonné demande les messages publiés sur ce sujet, il se connecte au serveur le plus proche. Celui-ci regroupe les données de tous les messages publiés sur le sujet, puis les envoie au client.
Pub/Sub est organisé en deux grandes parties : le plan de données, qui gère le transfert de messages entre les éditeurs et les abonnés, et le plan de contrôle, qui gère l'affectation des éditeurs et des abonnés aux serveurs du plan de données. Les serveurs du plan de données sont appelés des redirecteurs, et les serveurs du plan de contrôle sont des routeurs. Lorsque les éditeurs et les abonnés sont connectés aux redirecteurs auxquels ils sont affectés, ils n'ont pas besoin d'informations provenant des routeurs (tant que ces redirecteurs restent accessibles). Par conséquent, il est possible de mettre à jour le plan de contrôle de Pub/Sub sans perturber les clients déjà connectés et qui envoient ou reçoivent des messages.
Plan de contrôle
Le plan de contrôle Pub/Sub distribue les clients aux redirecteurs de manière à assurer adaptabilité, disponibilité et faible latence pour l'ensemble de ces clients. Tout redirecteur est capable de diffuser n'importe quel sujet ou abonnement aux clients. Lorsqu'un client se connecte à Pub/Sub, le routeur décide à quels centres de données le client doit se connecter en fonction de la distance réseau (mesure de la latence de la connexion entre deux points) la plus courte. Dans un centre de données particulier, le routeur tente de répartir la charge globale sur l'ensemble des redirecteurs disponibles. Pour cette tâche, le routeur doit atteindre un équilibre entre deux objectifs différents : (a) l'uniformité de la charge (idéalement, chaque redirecteur reçoit une charge égale) ; et (b) la stabilité des affectations (idéalement, un changement au niveau de la charge ou de l'ensemble de redirecteurs disponibles impacte un nombre minimal d'affectations existantes). Le routeur utilise une variante du système de hachage cohérent développé par Google Research pour atteindre un équilibre ajustable entre cohérence et uniformité. Le routeur fournit au client une liste numérotée de redirecteurs auxquels il peut envisager de se connecter. Cette liste numérotée peut changer suivant la disponibilité des redirecteurs et la forme de la charge émanant du client.
Un client reçoit cette liste de redirecteurs et se connecte à un ou plusieurs d'entre eux. Le client se connecte de préférence aux serveurs les plus recommandés par le routeur, mais il peut également prendre en compte toute défaillance survenue. Ainsi, il peut décider d'essayer les redirecteurs d'un centre de données différent si plusieurs tentatives auprès de centres plus proches ont échoué. Pour que ces détails de mise en œuvre soient cachés aux clients Pub/Sub, il existe un proxy de service entre les clients et les redirecteurs, qui réalise cette optimisation de la connexion pour le compte des clients.
Plan de données – La vie d'un message
Le plan de données reçoit les messages des éditeurs et les envoie aux clients. La meilleure façon de comprendre le plan de données de Pub/Sub consiste probablement à observer la vie d'un message, du moment où il est reçu par le service au moment où il n'est plus présent dans le service. Suivons donc les étapes du traitement d'un message. Pour les besoins de cette section, nous supposons que le sujet dans lequel le message est publié est associé à au moins un abonnement. En général, un message passe par les étapes suivantes :
Un éditeur envoie un message.
Le message est enregistré dans l'espace de stockage.
Pub/Sub envoie un accusé de réception à l'éditeur indiquant qu'il a bien reçu le message et garantit sa distribution à tous les abonnements associés.
En même temps qu'il enregistre le message dans son espace de stockage, Pub/Sub le distribue aux abonnés.
Les abonnés envoient un accusé de réception à Pub/Sub indiquant qu'ils ont traité le message.
Une fois qu'au moins un abonné de chaque abonnement a accusé réception du message, Pub/Sub supprime le message de son espace de stockage.
Pour commencer, un éditeur envoie à Pub/Sub un message dans un sujet. Ce message est chiffré par la couche proxy et envoyé à un redirecteur de publication, auquel l'éditeur est connecté. Pour en garantir la distribution, le message est immédiatement enregistré dans l'espace de stockage. Le redirecteur écrit initialement le message vers N clusters (N étant un nombre impair) et considère le message comme persistant lorsqu'il a été écrit dans au moins ⌈N/2⌉ clusters. Une fois le message persistant, le redirecteur de publication accuse réception du message auprès de l'éditeur et, à ce stade, Pub/Sub garantit que le message sera distribué à tous les abonnements associés.
Au sein de chaque cluster, le message est écrit sur M disques indépendants (où M est un nombre impair), ce qui nécessite que les données figurent sur ⌈M/2⌉ disques pour être considérées comme persistantes sur ce cluster. Au total, tout message publié sera écrit sur au moins ⌈M/2⌉ disques indépendants dans ⌈N/2⌉ clusters avant d'être considéré comme persistant, et finira par être répliqué sur N*M disques.
Le redirecteur de publication possède une liste de tous les abonnements associés à un sujet. Il est responsable de la persistance des messages publiés ainsi que des métadonnées décrivant quels messages ont fait l'objet d'un accusé de réception par chaque abonnement. L'ensemble de messages reçus et stockés par un redirecteur de publication pour un sujet donné, ainsi que ce suivi des messages ayant fait l'objet d'un accusé de réception, est appelé "source des messages à publier". Suivant les exigences de débit pour le sujet, un même éditeur peut envoyer ses messages à plusieurs redirecteurs de publication et stocker des messages dans plusieurs sources des messages à publier. Différents éditeurs travaillant sur le même sujet peuvent également envoyer des messages à différents redirecteurs de publication. Chaque message est envoyé à un seul redirecteur chargé de publication. Pub/Sub ajuste de manière dynamique, à mesure que le débit change, le nombre de redirecteurs de publication recevant des messages pour un sujet particulier.
Les abonnés reçoivent des messages en se connectant aux redirecteurs d'abonnement, par lesquels les messages émis par les éditeurs sont transmis aux abonnés. Dans le cas d'un abonné pull, le concept de "connexion" signifie l'émission d'une requête pull. Dans le cas d'un abonné push, le concept de "connexion" signifie que son point de terminaison push est enregistré auprès de Pub/Sub. Une fois qu'un abonnement est créé, il est garanti que tous les messages publiés après ce moment lui seront remis : c'est ce que nous appelons une garantie de point de synchronisation.
Chaque redirecteur d'abonnement doit demander des messages aux redirecteurs de publication disposant de sources des messages à publier pour le sujet. Comme les éditeurs, les abonnés peuvent se connecter à plusieurs redirecteurs d'abonnement pour recevoir des messages. Ainsi, les redirecteurs d'abonnement n'ont pas tous besoin de connaître ou recevoir des messages de chaque source des messages à publier pour un sujet. Il s'agit d'une propriété importante qui contribue à l'évolutivité horizontale de Pub/Sub. Suivant le débit des messages distribués aux abonnés, Pub/Sub ajuste de manière dynamique, à mesure que le débit change, le nombre de redirecteurs d'abonnement par l'intermédiaire desquels les abonnés reçoivent des messages liés à un sujet particulier.
Pour demander les messages dont il a besoin, un redirecteur d'abonnement adresse des requêtes à un ou plusieurs redirecteurs de publication disposant de sources des messages à publier dans un sujet donné. Le redirecteur de publication envoie les messages non confirmés au redirecteur d'abonnement, qui les relaie ensuite à un abonné.
Une fois qu'un abonné a traité un message, il envoie un accusé de réception au redirecteur d'abonnement. Le redirecteur d'abonnement relaie cet accusé de réception au redirecteur de publication, qui enregistre l'accusé de réception dans la source des messages à publier. Après que tous les abonnements d'un sujet ont accusé réception d'un message, celui-ci est supprimé de manière asynchrone de la source des messages à publier et de l'espace de stockage.
Différents messages concernant un seul sujet et un seul abonnement peuvent être acheminés par de nombreux éditeurs, abonnés, redirecteurs de publication et redirecteurs d'abonnement. Les éditeurs peuvent publier des messages simultanément pour plusieurs redirecteurs simultanément, et les abonnés peuvent se connecter à plusieurs redirecteurs d'abonnement pour recevoir des messages. Par conséquent, le flux de messages à travers les connexions entre éditeurs, abonnés et redirecteurs peut être complexe. Le schéma suivant illustre le flux possible des messages pour un sujet et un abonnement donnés. Les différentes couleurs indiquent les différents chemins que les messages peuvent emprunter depuis les éditeurs vers les abonnés :
S'assurer que Pub/Sub reste opérationnel
Pour qu'un système distribué tel que Pub/Sub reste opérationnel et serve efficacement tous les clients, il faut beaucoup de visibilité et de contrôle sur le système. La maintenance du service incombe à nos ingénieurs en fiabilité des sites (SRE, Site Reliability Engineers). Pour Pub/Sub, ces ingénieurs sont répartis dans le monde entier afin d'être disponibles 24h/24, 7j/7.
Environnements
La maintenance d'un système tel que Pub/Sub implique tout d'abord de pouvoir tester le logiciel avant son utilisation par les clients. Pour cela, il existe trois environnements Pub/Sub : test, préproduction et production. Les environnements de test et de préproduction ne reçoivent aucun trafic client. Ils ne contiennent que nos tests et notre surveillance fonctionnant en continu pour détecter tout problème avec les versions. Ces environnements reçoivent les nouvelles versions du logiciel avant la mise en production. La différence entre les environnements de test et de préproduction réside dans le fait que ce dernier est une réplique exacte de ce qui figure actuellement (ou figurera très bientôt) dans l'environnement de production, y compris la version du logiciel et les indicateurs de ligne de commande. L'environnement de test peut comporter des fonctionnalités actives, mais faisant encore l'objet d'un travail de développement, et dont le déploiement est prévu par la suite.
Déploiement
La procédure de déploiement et de test de Pub/Sub est conçue pour minimiser l'impact potentiel. Voyons les étapes typiques du déploiement d'une nouvelle version de Pub/Sub :
Vérification de la réussite de tous les tests unitaires et d'intégration
Compilation d'une nouvelle version de tous les serveurs
Déploiement des nouveaux serveurs dans les environnements de test et de préproduction
Exécution des serveurs dans les environnements de test et de préproduction pendant plusieurs jours
S'il n'y a pas de problème connu, déploiement des serveurs dans une version Canary, qui correspond à un sous-ensemble de l'environnement de production hébergeant un trafic client limité
Si aucun problème n'est détecté dans la version Canary, déploiement progressif des serveurs dans l'environnement de production sur plusieurs jours, jusqu'au déploiement complet
Pub/Sub étant conçu pour résister aux pannes (par exemple grâce à la séparation entre le plan de contrôle et le plan de données), le déploiement de nouvelles versions de serveurs est transparent pour les clients et ne devrait avoir aucun impact sur les performances perçues.
Surveillance
Pour garder Pub/Sub opérationnel, il est essentiel de détecter et de résoudre automatiquement les problèmes avant qu'ils n'affectent les utilisateurs finaux. Cela nécessite une surveillance approfondie du système. L'équipe SRE (Site Reliability Engineering) gère un ensemble d'indicateurs de niveau de service (SLI, Service level indicators) qui sont des métriques bien définies décrivant le comportement du système. Les métriques peuvent inclure le "temps requis pour effectuer une requête CreateSubscription" ou le "taux d'erreurs générées par les requêtes de publication". Ces métriques sont mesurées de différentes manières. Certaines sont strictement internes à nos redirecteurs et routeurs. Elles mesurent, par exemple, le temps nécessaire pour écrire des messages sur le disque.
Toutes ces mesures aident à définir des objectifs de niveau de service (SLO) internes, des cibles spécifiques pour les SLI. Par exemple, "une requête CreateSubscription ne doit pas prendre plus de cinq secondes." Les SRE sont avertis en cas de non-respect des SLO et doivent répondre aux alertes dans les cinq minutes.
Un contrat de niveau de service répertorie les SLO qui définissent nos garanties de performance vis-à-vis de nos utilisateurs finaux et les conséquences si nous ne les respectons pas. Vous pouvez consulter le contrat de niveau de service de Pub/Sub.
Nous assurons la maintenance d'un ensemble de clients qui publient et s'abonnent de façon prévisible. On les appelle des sondes. Les sondes existent à la fois pour le plan de données et le plan de contrôle. Chacun de nos probers réalise des actions spécifiques, exactement comme le ferait un client, et mesure la durée de l'opération. Par exemple, nous avons un prober qui génère un abonnement, publie un message et observe le temps nécessaire pour créer l'abonnement et recevoir le message. Si les probers déterminent qu'une des métriques mesurées ne correspond pas aux attentes, les ingénieurs SRE sont alertés.
Les métriques utilisées pour nos serveurs et nos probers sont visibles dans plusieurs tableaux de bord internes, ce que consultent en premier nos ingénieurs SRE lorsqu'ils diagnostiquent des problèmes potentiels. Ces pages permettent d'accéder rapidement aux statistiques et graphiques relatifs à l'ensemble du service. Ils peuvent également être décomposés par sujet, par centre de données ou par tâche individuelle.
Les métriques les plus intéressantes pour les utilisateurs du service sont accessibles via Google Cloud Monitoring.
Commandes
Nous disposons de plusieurs commandes pour nous aider à optimiser les performances de Pub/Sub. Certaines de ces commandes sont conçues pour l'assistance en cas de panne au niveau d'un centre de données ou d'une machine. Nous pouvons placer des contraintes de routage sur tout ou partie des sujets. Il s'agit de règles spécifiant des ensembles de clients autorisés ou non à se connecter à certains ensembles de redirecteurs. Nous utilisons des contraintes de routage afin de dévier le trafic associé à des tâches de redirecteurs individuels ou à des centres de données entiers si ceux-ci ne fonctionnent pas comme prévu.
Le contrôle de flux est une autre fonctionnalité réglable à notre disposition. Cette fonctionnalité nous permet d'optimiser le débit tout en évitant les surcharges du service. Le contrôle de flux est une forme de gestion du trafic permettant de lisser au cours du temps les pics de charge soudains et inattendus, dans le but d'améliorer la stabilité du service. Le contrôle de flux fonctionne au niveau du système entier, ou bien par sujet ou par abonné, pour limiter le nombre de messages ou le nombre d'octets transférés ou en attente. Dans ce contexte, "en attente" signifie que le message a été remis au client, mais que celui-ci n'en a pas encore accusé réception. Le contrôle de flux et les contraintes de routage nous permettent d'optimiser les performances de Pub/Sub sans que les clients n'aient à s'inquiéter de ces détails de bas niveau.
Résumé
Les avantages en termes d'évolutivité, de disponibilité et de latence d'un service tel que Pub/Sub définissent la proposition de valeur pour les clients qui envisagent de passer à des services gérés dans le cloud. Un service de messagerie asynchrone doit être créé avec, dès le départ, ces fonctionnalités comme points de référence. Forte d'une expérience de plus de 10 ans dans la distribution fiable et rapide de nombreux messages, l'équipe Pub/Sub a développé et continue de maintenir un service capable de répondre aux exigences des produits les plus fondamentaux de Google. Désormais, ce même service est disponible pour tous nos clients externes qui souhaitent envoyer leurs messages dans le monde entier sans se soucier de savoir si leur système de messagerie peut gérer 2, 10 ou 100 fois leur charge actuelle.
Glossaire
Terme | Description |
---|---|
Cluster | Regroupement logique de machines partageant généralement le même domaine de défaillance (par exemple, un réseau local partagé et une alimentation partagée) |
Plan de contrôle | Couche de Pub/Sub qui gère l'affectation des éditeurs et des abonnés aux serveurs du plan de données |
Plan de données | Couche de Pub/Sub qui gère le transfert de messages entre les éditeurs et les abonnés |
Redirecteur | Serveur du plan de données |
Accès mondial aux données | Les clients abonnés et éditeurs Pub/Sub ignorent l'emplacement des données. Les opérations de routage et de stockage sont effectuées par le service lui-même, conformément à la stratégie de restriction d'emplacement |
Évolutif horizontalement | Capacité d'un service à gérer de manière transparente une charge accrue en augmentant le nombre d'instances de composants du service |
Message | Données qui transitent par Pub/Sub |
Distance réseau | Mesure de la latence de la connexion entre deux points |
Prober | Tâche jouant le rôle d'un client et effectuant de manière prévisible une ou plusieurs actions sur les serveurs Pub/Sub |
Sources des messages à publier | Ensemble de messages reçus et stockés par un redirecteur de publication, accompagné d'un ensemble d'ID de messages confirmés par tous les abonnements associés |
Service de publication et d'abonnement (Pub/Sub) | Service de messagerie où les expéditeurs de messages sont découplés des destinataires |
Éditeur | Client de Pub/Sub qui crée des messages et les envoie (les publie) dans un sujet spécifié |
Router | Serveur dans le plan de contrôle |
Contraintes de routage | Liste de règles indiquant quels redirecteurs les routeurs peuvent envoyer aux clients en tant que points de terminaison auxquels se connecter |
Contrat de niveau de service | Liste des SLO définissant les performances d'un système garanties aux clients et décrivant les conséquences si ces objectifs ne sont pas respectés |
Indicateur de niveau de service (SLI) | Métrique bien définie décrivant le comportement du système |
Objectif de niveau de service (SLO) | Objectif spécifique pour un indicateur de niveau de service |
Abonné | Client de Pub/Sub recevant des messages sur un abonnement spécifié |
Abonnement | Entité nommée qui représente un intérêt à recevoir tous les messages associés à un sujet particulier |
Garantie de point de synchronisation | Heure à laquelle un abonnement est créé, à partir de laquelle tous les messages publiés seront distribués aux abonnés. |
sujet | Entité nommée qui représente un flux de messages |