Comment nous avons créé (recréé !) Intune pour en faire un des meilleurs services cloud mis à l’échelle mondiale du marché

Ce n’est pas dans les habitudes de Microsoft, mais j’aimerais aujourd’hui partager avec vous un billet de blog (voir ci-dessous) rédigé à des fins internes uniquement.

Permettez-moi de répondre à votre première question : « Mais pourquoi partagez-vous ces informations ? »

En fait, lorsque je rencontre des clients qui opèrent leur propre transition numérique, j’entends souvent dire que les équipes informatiques (et leurs responsables) ont du mal à mettre à l’échelle leur infrastructure ou leurs applications, pas uniquement dans le cloud, mais aussi en termes d’exigences cloud lors de ce processus.

Pour l’avoir moi-même ressenti, je comprends parfaitement ce sentiment.

En partageant les informations ci-dessous, je souhaite expliquer comment nous avons créé notre propre service cloud mondial et vous permettre d’en tirer parti afin de créer votre propre solution.

Nous avons architecturé Intune à partir du cloud et pour le cloud, et avons réussi à nous doter du premier service de mobilité au monde et du seul cloud pouvant être réellement mis à l’échelle.

Cette architecture permet à nos clients d’atteindre leurs objectifs, de sauvegarder leurs données et de protéger leur propriété intellectuelle, et cela sans limites en termes de productivité et de mise à l’échelle.

Ce n’est pas tous les jours qu’il vous est permis de créer quelque chose à partir de rien (littéralement : Fichier-Nouveau), puis d’utiliser et d’optimiser ce que vous avez créé pour un service cloud évolutif capable de gérer des milliards de transactions par jour.

Intune nous a offert une de ces opportunités aussi rares qu’enrichissantes.

Ce que je retiens de ce billet de blog, c’est le génie des ingénieurs qui en sont à l’origine, car c’est bien ce dont il est question.  Lorsqu’on se penche sur le marché gigantesque (et toujours croissant) de la gestion mobile, Intune est unique en ce sens qu’il s’agit d’un véritable service cloud. D’autres solutions prétendent disposer d’un modèle cloud mais, par essence, elles ne sont tout simplement pas conçues en tant que service cloud.

L’équipe d’ingénierie Intune est devenue l’une des équipes Microsoft les plus sollicitées pour présenter les modalités de notre parcours vers un service cloud à grande échelle. Lorsque nous avons commencé à travailler sur Intune, Azure n’était qu’une petite lueur dans les yeux d’une poignée de formidables ingénieurs, et c’est la raison pour laquelle, l’architecture initiale n’a pas été créée sur Azure. En 2015, lorsque l’utilisation d’Intune a réellement évolué, nous avons compris qu’il nous fallait réachitecturer le service pour en faire un service Azure moderne, créé sur une architecture de micro-service cloud.

Nous avons pris là une formidable décision.

Avec le recul, la raison d’une telle décision était évidente :  lorsqu’un service évolue vers des dizaines de millions, puis des centaines de millions et enfin des milliards d’appareils et d’applications, seule une architecture cloud peut répondre à vos attentes en termes de fiabilité, d’évolutivité et de qualité. De même, sans architecture cloud, nos équipes d’ingénierie n’auraient pas été en mesure de répondre suffisamment vite aux besoins des clients.

Depuis que nous avons opéré ce changement, je ne compte plus les commentaires de clients ravis de la fiabilité et des performances constatées, ainsi que de la vitesse à laquelle nous proposons des innovations.

Et tout cela grâce à l’architecture.  L’architecture est vraiment primordiale.

Cette perspective architecturale est le fruit de nombreuses heures passées à examiner d’autres solutions avant de prendre la décision de recréer Intune. Avant de nous y atteler, nous avons longuement analysé et évalué un certain nombre de solutions concurrentes pour savoir s’il ne serait pas préférable d’opter pour l’une d’entre elles. Aucune des solutions envisagées ne relevait d’un service cloud, aucune. Il s’agissait en fait de produits client-serveur locaux classiques hébergés dans un centre de données et appelés services cloud.

Il n’était pas question d’hyperscale.

La présence d’un numéro de version vous permet de facilement savoir si le produit relève d’un modèle client-serveur ou d’un service de cloud. Une mention telle que « Produit X v8.3 » indique d’emblée qu’il ne s’agit pas d’un service cloud.  Aucun service cloud ne présente de numéro de version lorsqu’il est mis à jour plusieurs fois par jour.

J’ai hâte de voir ce qu’Intune nous réserve, car seuls des services cloud permettent d’appréhender certains scénarios. Ainsi, l’équipe d’ingénierie Intune propose déjà des solutions pour répondre à des problèmes que nos concurrents n’ont pas encore détectés, ce qui signifie que l’expertise de cette équipe ne fera que s’étoffer pour anticiper et répondre aux besoins de nos clients.

En tant que responsable en ingénierie, c’est passionnant d’imaginer ce que cela apportera aux services et outils que nous créerons pour nos clients, ainsi qu’à l’arsenal de moyens dont nous disposerons pour aider nos clients à mener à bien de nouveaux projets.

Si vous n’avez pas encore opté pour Intune, accordez-vous quelques minutes pour lire ce billet et prenez contact avec nous.

 


 

Parcours Intune vers un service cloud distribué à l’échelle mondiale hautement évolutif

 

Depuis le 2nd semestre 2015, Intune, qui fait partie d’Enterprise Mobility + Security (EMS), a entamé son parcours en tant que service à la croissance la plus rapide de l’histoire de Microsoft. Les premiers signes de cette croissance rapide se sont traduits par une hausse rapide des opérations principales à grande échelle. Parallèlement, nous avons innové dans différents domaines de notre service au sein d’Intune, dans Azure, ainsi que dans d’autres domaines dépendants. Équilibrer dans un court délai innovation et croissance rapide était un défi aussi difficile qu’intéressant qu’il nous a fallu relever dans Intune. Malgré la présence de certaines mesures d’atténuation, nous souhaitions disposer d’une longueur d’avance en termes de mise à l’échelle et de performances, et ce rythme de croissance a fait office de déclencheur pour accélérer notre parcours vers des services cloud distribués à l’échelle mondiale matures et évolutifs. Au cours des mois qui ont suivi, nous avons entrepris d’importants changements en termes d’architecture, de fonctionnement et d’exécution de nos services.

Ce billet fait partie d’une série de quatre billets de blog qui décriront le parcours des services cloud Intune pour devenir l’un des services cloud les plus matures et les plus évolutifs exécutés sur Azure. Nous proposons aujourd’hui l’un des services fonctionnant à grande échelle les plus aboutis et continuons d’améliorer les six piliers que sont la disponibilité, la fiabilité, les performances, l’évolutivité, la sécurité et l’agilité.

Architecture et contexte, et réactions rapides pour améliorer la satisfaction des clients et influer de manière positive sur la croissance de l’entreprise.

  1. Nos mesures et actions proactives pour préparer la croissance immédiate.
  2. Actions visant à rendre le service hautement disponible et évolutif, au même niveau que d’autres services de classe mondiale.
  3. Cheminement vers un service novateur servant d’exemple pour diverses opérations à grande échelle dans des systèmes distribués.

Chaque billet de blog résumera les enseignements tirés et expliquera succinctement le sujet. Le premier billet de cette série est décrit ci-dessous. Les trois autres sujets feront l’objet d’autres billets disponibles au cours des prochains mois.

Contexte et architecture

En 2015, Intune combinait un ensemble de services s’exécutant sur des machines physiques hébergées dans un centre de données privé et un ensemble de services distribués s’exécutant sur Azure. En 2018, tous les services Intune ont été transférés sur Azure. Ce billet et les suivants se concentreront sur les services distribués s’exécutant sur Azure. La migration des services s’exécutant sur des machines physiques vers Azure relève d’un autre parcours qui fera peut-être l’objet d’un billet de blog ultérieur. Le reste de cette section se concentre sur le contexte et l’architecture en 2015.

Vue architecturale globale

Les services cloud d’Intune sont créés sur Azure Service Fabric (ASF). Tous les services sont déployés sur un cluster ASF constitué d’un groupe de nœuds frontaux (FE) et intermédiaires (MT). Les nœuds FE sont hébergés sur sku A4 (14 Go, 8 cœurs). Les nœuds MT sont hébergés sur sku A7 (56 Go, 8 cœurs). Un cluster est isolé et indépendant des autres clusters. Hébergés dans des abonnements et des centres de données bien distincts, les clusters ne peuvent en aucun cas accéder les uns aux autres. Il existe 18 clusters ASF de ce type dans le monde, répartis dans 3 régions : Amérique du Nord (NA), Europe (EU) et Asie-Pacifique (AP). Chaque cluster ASF dispose d’un ensemble de services identiques déployés, et exécute des fonctionnalités identiques. Ces services comprennent des services sans état, ainsi que des services partitionnés avec état. La figure 1 illustre la vue architecturale globale.

Figure 1 : Clusters globaux Intune (aussi appelés Unité d’échelle Azure, ASU) – Vue architecturale (2015) sku (14 Go, 8 cœurs). Les nœuds MT sont hébergés sur sku A7 (56 Go, 8 cœurs). 

Détail architectural des clusters

Au sein de chaque cluster, plus de 5 000 services s’exécutent avec un ensemble d’environ 80 types uniques de micro-services sans état et d’environ 40 types uniques de micro-services avec état. Les services sans état exécutent plusieurs instances sur tous les nœuds FE routés par Azure Load Balancer. Les services avec état et certains services de valeur sans état s’exécutent sur les nœuds MT. Les services avec état reposent sur une architecture en mémoire mise en place en interne en tant que base de données No-SQL (rappelons que nous parlons ici de 2015).

Le stockage en mémoire avec état implémenté combine des arborescences AVL et des jeux de hachage permettant des écritures, obtentions, analyses de table et recherches d’index secondaires extrêmement rapides. Ces services avec état sont partitionnés à des fins de montée en charge. Chaque partition dispose de cinq réplicas pour gérer la disponibilité. L’un de ces cinq réplicas fait office de réplica principal où toutes les requêtes sont gérées. Les quatre réplicas restants sont des réplicas secondaires issus du réplica principal. Les opérations de données de certains de nos services impliquent une cohérence forte et dès lors, il nous faut disposer d’un quorum de réplicas afin de satisfaire les écritures. Dans ces scénarios, nous privilégions CP à AP dans le théorème CAP, à savoir, lorsqu’un quorum de réplicas n’est pas disponible, les écritures échouent et s’ensuit une perte de disponibilité. Certains de nos scénarios sont corrects en termes de cohérence éventuelle, et AP est préférable à CP, mais pour des raisons de simplicité, notre architecture initiale prenait en charge une cohérence forte de tous les services. Aussi, à ce stade, nous avons opté pour CP.

ASF se révèle efficace à bien des égards, notamment en ce qui concerne le regroupement dense de services dans le cluster. Le nombre type de processus s’exécutant sur chaque nœud MT varie de 30 à 50 hébergeant plusieurs réplicas avec état. Il traite également très bien toutes les complexités de gestion et d’orchestration de basculement et de mouvement, effectuant des mises à niveau progressives pour tous nos déploiements de services et un équilibrage de charge sur le cluster. En cas de disparition du réplica principal, un réplica secondaire est automatiquement promu en tant que réplica principal par ASF, et un nouveau réplica secondaire est créé pour répondre à l’exigence de 5 réplicas. Le nouveau réplica secondaire initie et complète un transfert de données de mémoire à mémoire entre le réplica principal et le réplica secondaire. En outre, nous sauvegardons régulièrement les données dans un stockage blob/table avec un RPO de 10 minutes si tous les réplicas sont perdus en cas de sinistre ou de perte de partition. La figure 2 illustre la vue du cluster. La figure 2 illustre la vue du cluster.

Figure 2 – Mise à l’échelle : Unité d’échelle Azure Intune (aussi appelée cluster ou ASU) Architecture (2015)RPO de récupération si tous les réplicas sont perdus en cas de sinistre ou de perte de partition. La figure 2 illustre la vue du cluster. La figure 2 illustre la vue du cluster.

Problèmes

Comme mentionné précédemment, face à la croissance d’utilisation rapide (qui s’échelonnait de 3 à 7 milliards de transactions par jour), fin 2015 et début 2016, nos services back-end se sont mis à enregistrer une augmentation colossale du trafic. Nous avons alors commencé à chercher des solutions tactiques pour remédier sans délais aux problèmes découlant de cette croissance rapide.

Problème 1 :

Nous avons d’emblée compris qu’il nous fallait disposer de données de télémétrie et d’alertes. À ce stade, l’échelle à laquelle nous avions besoin de données de télémétrie évoluait rapidement du fait de l’infrastructure Azure sous-jacente, et pour diverses raisons, calendriers de disponibilité générale notamment, il ne nous était pas possible d’en tirer immédiatement parti. Ainsi, d’un point de vue tactique, il nous a fallu imaginer dans les meilleurs défais des solutions d’instrumentation et de diagnostic afin d’obtenir suffisamment de données pour prendre des mesures d’atténuation. Une fois la télémétrie en place, nous avons commencé à collecter des données sur les principaux problèmes à examiner pour y apporter des solutions.

Les investissements rapides réalisés en termes de télémétrie ont porté leurs fruits. Nous avons réussi à mettre en place des solutions tactiques et itérer sans plus attendre. Tous les autres problèmes étaient liés à ce court terme, la réalisation d’investissements à fort impact en télémétrie.

Problème 2 :

Les données de télémétrie nous ont permis de comprendre que certaines partitions traitaient d’importants volumes de données. Une seule partition pouvait stocker des millions d’objets et les taux de transactions atteignaient jusqu’à six milliards par jour sur les clusters. Plus de données rimaient avec plus de transfert de données lorsque des réplicas secondaires devaient être créés en cas de disparition du réplica principal, des réplicas secondaires ou d’équilibrage de charge. Plus il y avait de données et plus il fallait de temps pour créer les réplicas secondaires avec la mémoire et les coûts UC correspondants.

Le plus clair de ce temps était du à la sérialisation/désérialisation des données nécessaires au transfert entre réplicas lors de la reconstruction. Nous utilisions un sérialiseur de contrat de données et, après avoir examiné les performances de nombreux sérialiseurs, nous avons opté pour Avro. Avro nous a permis d’améliorer le débit et l’UC de 50 %, et de réduire considérablement le délai de reconstruction. Par exemple, pour un transfert de données de 4 Go, le délai de reconstruction, qui pouvait prendre jusqu’à 35 minutes, était réduit à <= 20 minutes. Ce délai n’était pas optimal, mais il nous fallait trouver une solution immédiate, et en ce sens, cette solution nous a été d’une grande aide. Dans mon prochain billet, je vous expliquerai comment nous avons réussi à réduire ces 20 minutes en quelques secondes.

Problème 3 :

La croissance d’utilisation a également généré de nouveaux modèles de trafic et de recherche pour nos algorithmes, des algorithmes pas totalement optimisés à des fins d’efficacité (UC/mémoire). Nous avons conçu une recherche d’index secondaire efficace avec arborescences AVL, mais certains modèles de recherche pouvaient être encore plus optimisés. Nous avons supposé que les arborescences d’index secondaires seraient plus petites que l’arborescence principale à l’origine des analyses de table complètes, et pourraient répondre à nos besoins. Cependant, lorsque nous avons examiné les taux d’UC élevés, nous avons remarqué un modèle de trafic à l’origine des besoins d’UC pour certaines recherches d’index secondaires. Une analyse approfondie a montré que la pagination et l’ordre des recherches en présence de millions d’objets dans un index secondaire pouvaient entraîner une utilisation extrêmement élevée de l’UC et impacter tous les services exécutés sur ce nœud.

Ces informations nous ont permis de réagir immédiatement et de concevoir un autre algorithme. Pour la pagination et l’ordre des recherches, nous avons conçu et implémenté une approche avec segmentation max afin de remplacer l’arborescence AVL. La complexité temporelle des insertions et des recherches constitue un meilleur ordre de grandeur en termes de segmentation max. L’insertion d’objets 1M nous a permis de réduire le délai de 5 secondes à 250 millisecondes, et nous avons constaté une amélioration de l’ordre (du tri) pour les objets 1M de 5 secondes à 1,5 seconde. Compte tenu du nombre de requêtes de recherche lié à ces différentes opérations, cette amélioration s’est accompagnée d’une nette diminution de la consommation de mémoire et d’UC dans le cluster.

Problème 4 :

L’impact sur la croissance était essentiellement visible lors des déploiements/mises à jour. Et ces problèmes se sont aggravés lorsqu’Azure a redémarré les nœuds FE et MT dans le cadre du calendrier de mise à jour de son système d’exploitation. Ces nœuds ont été redémarrés par domaine de mise à niveau (UD), de manière séquentielle, avec une limite stricte de 20 minutes par UD avant de passer à l’UD suivant.

Ces mises à niveau ont révélé deux catégories de problèmes :

  • Le nombre de réplicas des services avec état était égal au nombre d’UD (à savoir, 5). Ainsi, lors de la mise à niveau d’un UD, ASF devait déplacer tous les réplicas de cet UD vers l’un des quatre autres, tout en respectant diverses contraintes, notamment la bonne distribution des réplicas afin de conserver les positionnements de domaine d’erreur, le réplica principal/les réplicas secondaires situés sur des nœuds, etc. Dès lors, ces mises à niveau impliquaient d’importants déplacements des réplicas. Après le problème 2 mentionné précédemment, nous savions que certaines reconstructions pouvaient nécessiter jusqu’à 20 minutes, ce qui signifiait que les réplicas secondaires n’étaient pas totalement prêts avant la mise à niveau de l’UD suivant. Suite à cela, nous perdions le quorum, car le nombre de réplicas actifs était insuffisant pour satisfaire les écritures lors des mises à niveau. La figure 3 illustre l’effet des évolutions de densité des réplicas lors des mises à niveau. La forte augmentation de quelque 350 réplicas à quelque 1000 réplicas pour l’un de nos services témoigne de l’ampleur de la reconstruction qui avait lieu. Notre réaction immédiate a été d’augmenter le SKU pour soulager les nœuds, mais la plateforme sous-jacente n’est pas parvenue à prendre en charge la mise à niveau du SKU.  Nous aurions alors dû effectuer un basculement vers un nouveau cluster, ce qui passait par une migration des données. Il s’agissait là d’une procédure particulièrement complexe et nous avons écarté cette idée. J’expliquerai, dans un prochain billet, comment nous avons surmonté cette limite.
  • Les équipes Intune et ASF ont procédé à une analyse approfondie de ce problème et, avec l’aide de l’équipe ASF, nous avons finalement opté pour une configuration optimale constituée de quatre réplicas avec cinq UD, de manière à veiller à ce qu’un UD soit toujours disponible pour les réplicas supplémentaires et d’éviter les mouvements excessifs des réplicas. Cette configuration a nettement amélioré la stabilité de notre cluster, et la densité des réplicas delta 3x lors des mises à niveau a baissé de 50 à 75 %.

 

Figure 3 : Nombre de réplicas et impact de la densité lors des mises à niveau

 

Enfin, nous avons également remarqué que notre cluster pouvait être mieux équilibré en termes de nombre de réplicas et de consommation de mémoire. Certains nœuds étaient fortement utilisés et d’autres quasiment inactifs. De toute évidence, cela exerçait une pression inutile sur les nœuds très chargés en cas de pics de trafic ou de mises à niveau. La solution a consisté à implémenter des métriques, des rapports et une configuration d’équilibrage de charge dans nos clusters. Les figures 4 et 5 illustrent mieux l’impact de cette solution. Les lignes bleues correspondent à l’équilibrage suite à nos améliorations. L’axe X correspond au nom du nœud que nous avons utilisé.

 

Figure 4 : Nombre de réplicas par nœud avant et après les améliorations d’équilibrage de charge.

 

Figure 5 : Consommation de mémoire par nœud avant et après les améliorations d’équilibrage de charge.

 

Enseignements

  • Nous avons tiré quatre enseignements de cette expérience, enseignements qui, à mon sens, peuvent s’appliquer à tout service cloud d’envergure :
  • Faites des données de télémétrie et des alertes un des points critiques de votre conception. Surveillez les données de télémétrie et les alertes, itérez et affinez dans un environnement de pré-production avant de proposer la fonctionnalité à vos clients en production.
  • Soyez au fait de vos dépendances. Si votre solution de mise à l’échelle ne s’aligne pas sur votre plateforme dépendante, rien ne va plus. À titre d’exemple, si la montée en charge de votre solution consiste à passer de 10 à 500 nœuds, assurez-vous que la plateforme dépendante (Azure, AWS, etc.) prenne en charge cette évolution, de même que le laps de temps requis. Par exemple, en présence d’une limite permettant une augmentation de quelques nœuds à la fois, vous devez ajuster votre mécanisme réactif (alertes, etc.) pour prendre en compte ce laps de temps. La mise à l’échelle en est un autre exemple. Si votre solution de mise à l’échelle consiste à effectuer une mise à niveau de sku, assurez-vous que votre plateforme dépendante prenne en charge la mise à niveau d’un sku à faible performance vers un sku à haute performance.
  • Vérifiez continuellement vos hypothèses. De nombreux services et plateformes cloud continuent d’évoluer et les hypothèses formulées il y a quelques mois peuvent ne plus être valides à bien des égards, notamment : conception/architecture de la plateforme dépendante, solutions alternatives optimisées, fonctionnalités obsolètes, etc. Une partie de cette tâche pourrait consister à surveiller vos chemins de code principal afin d’y détecter les changements de modèles de trafic et de veiller à ce que la conception, les algorithmes et l’implémentation en place soient toujours valides. Les modèles d’utilisation du trafic des services cloud évoluent, et une solution valide il y a quelques mois peut ne plus suffire et devoir être revue/remplacée par une solution plus efficace.
  • Faites de la planification de la capacité une priorité. Déterminez comment vous pouvez effectuer une analyse de capacité prédictive et examinez-la de manière régulière. C’est toute la différence entre un comportement réactif et proactif pour les problèmes d’échelle impactant les clients.

Conclusion

L’implémentation et le déploiement de toutes les solutions ci-dessus à des fins de production ont nécessité entre 3 et 4 mois. En avril 2016, les résultats étaient très encourageants. La stabilité, la disponibilité et la fiabilité de notre cluster ont été nettement améliorées. Nos clients l’ont également ressenti et ont formulé des commentaires particulièrement positifs sur les améliorations apportées en termes de fiabilité et de stabilité. En plus d’être particulièrement encourageante, cette étape nous a permis de tirer des enseignements qui ont ouvert la voie à de nouvelles améliorations. Nous avions entamé notre parcours vers un service cloud distribué mature et évolutif.

Veuillez noter que le contenu inclus dans ces billets de blog décrit des fonctionnalités pouvant varier selon le marché. Pour plus d’informations sur les offres de produit spécifiques de votre marché, consultez la page Microsoft 365, Office 365, Windows 10 ou Enterprise Mobility + Security.
Il se peut que le contenu de ces articles ne soit pas disponible dans votre langue.