Approches architecturales pour le calcul dans les solutions multilocataires
La plupart des solutions informatiques sont constituées de ressources de calcul d’un type ou d’un autre, telles que des couches Application et Web, des processeurs de traitement par lot, des tâches planifiées, voire des ressources spécialisées comme les GPU et le calcul haute performance (HPC). Les solutions multilocataires tirent souvent parti des ressources de calcul partagées, car une densité plus élevée de locataires par rapport à l’infrastructure réduit les coûts opérationnels et la gestion. Vous devez prendre en compte les exigences en matière d’isolation et connaître les implications d’une infrastructure partagée.
Cet article fournit une aide relative aux considérations et aux exigences qui sont essentielles pour les architectes de solutions lors de la planification d’un niveau de calcul multilocataire. Cela comprend des modèles courants pour l’application de l’architecture multilocataire aux services de calcul, ainsi que des antimodèles à éviter.
Principaux éléments et exigences à prendre en compte
L’architecture multilocataire et le modèle d’isolation que vous choisissez ont un impact sur la mise à l’échelle, le niveau de performance, la gestion de l’état et la sécurité de vos ressources de calcul. Dans cette section, nous allons examiner certaines des décisions clés que vous devez prendre lorsque vous planifiez une solution de calcul mutualisée.
Scale
Les systèmes doivent fonctionner de manière adéquate en fonction de l’évolution de la demande. Au fur et à mesure que le nombre de locataires et la quantité de trafic augmentent, vous pourriez avoir besoin d’augmenter la capacité de vos ressources, pour suivre le nombre croissant de locataires et maintenir un taux de performance acceptable. De même, lorsque le nombre d’utilisateurs actifs ou la quantité de trafic diminue, vous devez automatiquement réduire la capacité de calcul pour réduire les coûts, mais vous devez le faire avec un impact minimal sur les utilisateurs.
Si vous déployez des ressources dédiées pour chaque locataire, vous avez la possibilité de mettre à l’échelle les ressources de chaque locataire de manière indépendante. Dans une solution où les ressources de calcul sont partagées entre plusieurs locataires, si vous mettez ces ressources à l’échelle, tous ces locataires peuvent utiliser la nouvelle échelle. Toutefois, ils souffriront tous si l’échelle est insuffisante pour gérer leur charge globale. Pour plus d’informations, consultez le problème du voisin bruyant.
Lorsque vous créez des solutions cloud, vous pouvez choisir de les mettre à l’échelle horizontalement ou verticalement. Dans une solution multilocataire avec un nombre croissant de locataires, la mise à l’échelle horizontale offre généralement une plus grande flexibilité et un plafond d’échelle global plus élevé.
Les problèmes de performances passent souvent inaperçus jusqu’à ce qu’une application soit en charge. Vous pouvez utiliser un service complètement managé, tel qu’Azure Load Testing, pour découvrir le comportement de votre application en situation de stress.
Déclencheurs de mise à l’échelle
Quelle que soit l’approche utilisée pour la mise à l’échelle, vous devez généralement planifier les déclencheurs qui entraînent la mise à l’échelle de vos composants. Lorsque vous avez des composants partagés, tenez compte des modèles de charge de travail de chaque locataire qui utilise les ressources afin de vous assurer que la capacité approvisionnée peut répondre à la capacité totale requise et de réduire le risque qu’un locataire soit confronté au problème du voisin bruyant. Vous pouvez également planifier la capacité de mise à l’échelle en considérant le nombre de locataires. Par exemple, si vous mesurez les ressources que vous utilisez pour desservir 100 locataires, vous pouvez mettre à l’échelle, au fur et à mesure que vous intégrez de nouveaux locataires, de manière à ce que vos ressources doublent pour chaque tranche supplémentaire de 100 locataires.
État
Les ressources de calcul peuvent être sans état ou avec état. Les composants sans état ne conservent aucune donnée entre les requêtes. Du point de vue de la scalabilité, il est souvent facile d’effectuer un scale-out des composants sans état, car vous pouvez rapidement ajouter de nouveaux rôles de travail, de nouvelles instances ou de nouveaux nœuds, et ils peuvent immédiatement commencer à traiter les requêtes. Si votre architecture le permet, vous pouvez également réutiliser les instances affectées à un locataire et les allouer à un autre locataire.
Les ressources à état peuvent être subdivisées en fonction du type d’état qu’elles conservent. L’état persistant est celui des données qui doivent être stockées de manière permanente. Dans les solutions cloud, vous devez éviter de stocker un état persistant dans votre couche de calcul. Utilisez plutôt des services de stockage tels que des bases de données ou des comptes de stockage. L’état transitoire est celui des données stockées temporairement, notamment les caches en mémoire en lecture seule et le stockage de fichiers temporaires sur les disques locaux.
L’état transitoire est souvent utile pour améliorer le niveau de performance de votre couche Application, en réduisant le nombre de requêtes adressées aux services de stockage du serveur principal. Par exemple, lorsque vous utilisez un cache en mémoire, vous pouvez traiter les demandes de lecture, sans vous connecter à une base de données et sans effectuer une requête intensive que vous avez récemment effectuée quand vous avez servi une autre requête.
Dans les applications sensibles à la latence, le coût de l’hydratation du cache peut devenir significatif. Une solution multilocataire peut exacerber ce problème si chaque locataire a besoin de mettre en cache des données différentes. Pour atténuer ce problème, certaines solutions utilisent l’affinité de session pour s’assurer que toutes les requêtes d’un utilisateur ou d’un locataire spécifique sont traitées par le même nœud Worker de calcul. Bien que l’affinité de session puisse améliorer la capacité de la couche Application à utiliser efficacement son cache, elle rend également plus difficile la mise à l’échelle et l’équilibrage de la charge de trafic entre les rôles de travail. Ce compromis doit être soigneusement étudié. Pour de nombreuses applications, l’affinité de session n’est pas obligatoire.
Il est également possible de stocker des données dans des caches externes, comme Azure Cache pour Redis. Les caches externes sont optimisés pour une extraction de données à faible latence, tout en maintenant l’état isolé des ressources de calcul, de sorte qu’ils peuvent être mis à l’échelle et gérés séparément. Dans de nombreuses solutions, les caches externes vous permettent d’améliorer le niveau de performance des applications, tout en conservant la couche de calcul sans état.
Important
Évitez les fuites de données entre les locataires lorsque vous utilisez des caches en mémoire ou d’autres composants qui maintiennent l’état. Par exemple, pensez à ajouter un identificateur de locataire à toutes les clés de cache, afin de vous assurer que les données sont séparées pour chaque locataire.
Isolation
Lorsque vous concevez une couche de calcul multilocataire, vous avez souvent le choix parmi plusieurs options pour le niveau d’isolation entre les locataires, notamment le déploiement de ressources de calcul partagées, à utiliser par tous les locataires, de ressources de calcul dédiées pour chaque locataire ou quelque chose entre ces deux extrêmes. Chaque option présente des inconvénients. Pour vous aider à choisir l’option qui convient le mieux à votre solution, réfléchissez à vos exigences en matière d’isolation.
Vous pouvez vous préoccuper de l’isolation logique des locataires et de la manière de séparer les responsabilités ou les stratégies de gestion appliquées à chaque locataire. Vous pouvez également être amené à déployer des configurations de ressources distinctes pour des locataires spécifiques, par exemple en déployant un SKU de machine virtuelle spécifique pour répondre à la charge de travail d’un locataire.
Quel que soit le modèle d’isolation que vous choisissez, assurez-vous de vérifier que les données de vos locataires restent isolées de manière appropriée, même lorsque les composants sont indisponibles ou ne fonctionnent pas correctement. Envisagez d’utiliser Azure Chaos Studio dans le cadre de votre processus standard de test automatisé pour introduire délibérément des erreurs qui simulent des pannes réelles et vérifiez que votre solution ne perd pas de données entre les locataires et fonctionne correctement même sous pression.
Approches et modèles à prendre en compte
Mise à l’échelle automatique
Les services de calcul Azure offrent différentes capacités pour mettre à l’échelle vos charges de travail. De nombreux services de calcul prennent en charge la mise à l’échelle automatique, ce qui vous oblige à déterminer quand vous devez mettre à l’échelle, ainsi que vos niveaux d’échelle minimum et maximum. Les options spécifiques disponibles pour la mise à l’échelle dépendent des services de calcul que vous utilisez. Consultez les exemples de services suivants :
- Azure App Service : Spécifiez des règles de mise à l’échelle automatique qui mettent votre infrastructure à l’échelle en fonction de vos besoins.
- Azure Functions : Faites votre choix parmi plusieurs options de mise à l’échelle, y compris un modèle de mise à l’échelle piloté par les événements qui effectue une mise à l’échelle automatique en fonction du travail effectué par vos fonctions.
- Azure Container Apps : Utilisez la mise à l’échelle automatique pilotée par les événements pour mettre à l’échelle votre application en fonction du travail qu’elle effectue et de sa charge actuelle.
- Azure Kubernetes Service (AKS) : Pour suivre le rythme des demandes de votre application, vous devrez peut-être ajuster le nombre de nœuds qui exécutent vos charges de travail. En outre, pour mettre rapidement à l’échelle les charges de travail des applications dans un cluster AKS, vous pouvez utiliser des nœuds virtuels.
- Machines Virtuelles : Un groupe de machines virtuelles identiques peut augmenter ou diminuer automatiquement le nombre d’instances de machine virtuelle qui exécutent votre application.
Modèle d’empreintes de déploiement
Pour plus d’informations sur la façon dont le modèle Empreintes de déploiement peut être utilisé pour prendre en charge une solution multilocataire, consultez Vue d’ensemble.
Modèle de consolidation des ressources de calcul
Le modèle Consolidation des ressources de calcul vous aide à obtenir une densité plus élevée de locataires par rapport à l’infrastructure de calcul en partageant les ressources de calcul sous-jacentes. En partageant les ressources de calcul, vous êtes souvent en mesure de réduire le coût direct de ces ressources. En outre, vos coûts de gestion sont souvent plus faibles, car il y a moins de composants à gérer.
Toutefois, la consolidation des ressources de calcul augmente la probabilité du problème du voisin bruyant. La charge de travail d’un locataire peut consommer une quantité disproportionnée de la capacité de calcul disponible. Vous pouvez souvent atténuer ce risque en vous assurant de mettre à l’échelle votre solution de manière appropriée et en appliquant des contrôles tels que des quotas et des limites d’API, afin d’éviter que les locataires ne consomment plus que leur juste part de la capacité.
Ce modèle est réalisé de différentes façons, en fonction du service de calcul que vous utilisez. Consultez les exemples de services suivants :
- Azure App Service et Azure Functions : Déployez des plans App Service partagés, qui représentent l’infrastructure du serveur d’hébergement.
- Azure Container Apps : Déployez des environnements partagés.
- Azure Kubernetes Service (AKS) : Déployez des pods partagés, avec une application prenant en charge l’architecture multilocataire.
- Machines Virtuelles : Déployez un ensemble unique de machines virtuelles à l’usage de tous les locataires.
Ressources de calcul dédiées par locataire
Vous pouvez également déployer des ressources de calcul dédiées pour chaque locataire. Les ressources dédiées atténuent le risque du problème du voisin bruyant, en garantissant que les ressources de calcul pour chaque locataire sont isolées des autres. Cela vous permet également de déployer une configuration distincte pour les ressources de chaque locataire, en fonction de ses besoins. Les ressources dédiées ont toutefois généralement un coût plus élevé, car la densité de locataires par rapport aux ressources est plus faible.
Selon les services de calcul Azure que vous utilisez, vous devez déployer différentes ressources dédiées, comme suit :
- Azure App Service et Azure Functions : Déployez des plans App Service distincts pour chaque locataire.
- Azure Container Apps : Déployez des environnements distincts pour chaque locataire.
- Azure Kubernetes Service (AKS) : Déployez des clusters dédiés pour chaque locataire.
- Machines Virtuelles : Déployez des machines virtuelles dédiées pour chaque locataire.
Ressources de calcul semi-isolées
Les approches semi-isolées vous obligent à déployer des aspects de la solution dans une configuration isolée, tout en partageant les autres composants.
Lorsque vous travaillez avec App Service et Azure Functions, vous pouvez déployer des applications distinctes pour chaque locataire, et vous pouvez héberger les applications sur des plans App Service partagés. Cette approche réduit le coût de votre couche de calcul, car les plans App Service représentent l’unité de facturation. Elle vous permet également d’appliquer une configuration et des stratégies distinctes à chaque application. Toutefois, cette approche introduit le risque du problème du voisin bruyant.
Azure Container Apps vous permet de déployer plusieurs applications dans un environnement partagé, puis d’utiliser Dapr et d’autres outils pour configurer chaque application séparément.
Azure Kubernetes Service (AKS) et Kubernetes de manière plus générale offrent une variété d’options pour l’architecture multilocataire, notamment les suivantes :
- Espaces de noms spécifiques aux locataires, pour l’isolation logique des ressources spécifiques au locataire, qui sont déployées sur des clusters et des pools de nœuds partagés.
- Nœuds ou pools de nœuds spécifiques au locataire sur un cluster partagé.
- Pods spécifiques aux locataires qui peuvent utiliser le même pool de nœuds.
AKS vous permet également d’appliquer une gouvernance au niveau des pods pour atténuer le problème du voisin bruyant. Pour plus d’informations, consultez Meilleures pratiques pour les développeurs d’applications qui gèrent des ressources dans Azure Kubernetes Service (AKS).
Il est également important de connaître les composants partagés dans un cluster Kubernetes et la façon dont ces composants peuvent être concernés par l’architecture multilocataire. Par exemple, le serveur d’API Kubernetes est un service partagé qui est utilisé dans l’ensemble du cluster. Même si vous fournissez des pools de nœuds spécifiques aux locataires pour isoler les charges de travail des applications des locataires, le serveur d’API peut être confronté à la contention d’un grand nombre de requêtes entre les locataires.
Antimodèles à éviter
Antimodèle : voisin bruyant
Chaque fois que vous déployez des composants qui sont partagés entre des locataires, le problème du voisin bruyant constitue un risque potentiel. Veillez à inclure la gouvernance et la surveillance des ressources afin d’atténuer le risque que la charge de travail de calcul d’un locataire soit affectée par l’activité d’autres locataires.
Fuite de données entre locataires
Les couches de calcul peuvent faire l’objet d’une fuite de données entre locataires, si elles ne sont pas correctement gérées. Ce n’est généralement pas un problème à prendre en compte lorsque vous utilisez un service multilocataire sur Azure, car Microsoft fournit des protections au niveau de la couche de plate-forme. Toutefois, lorsque vous développez votre propre application multilocataire, vérifiez si les ressources partagées (telles que les caches des disques locaux, la RAM et les caches externes) peuvent contenir des données qu’un autre locataire peut visualiser ou modifier par inadvertance.
Antimodèle Serveur frontal occupé
Pour éviter l’antimodèle Serveur frontal occupé, ne laissez pas votre couche frontale effectuer une grande partie du travail qui pourrait être effectué par d’autres composants ou couches de votre architecture. Cet antimodèle est particulièrement important lorsque vous créez des serveurs frontaux partagés pour une solution multilocataire, car un serveur frontal occupé dégradera l’expérience de tous les locataires.
Au lieu de cela, envisagez d’utiliser un traitement asynchrone en faisant appel à des files d’attente ou à d’autres services de messagerie. Cette approche vous permet également d’appliquer des contrôles de qualité de service (QoS) aux différents locataires, en fonction de leurs besoins. Par exemple, tous les locataires peuvent partager une couche frontale commune, mais les locataires qui paient pour un niveau de service plus élevé peuvent disposer d’un ensemble plus important de ressources dédiées pour traiter le travail de leurs messages en file d’attente.
Mise à l’échelle non élastique ou insuffisante
Les solutions multilocataires sont souvent mises à l’échelle par à-coups. Les composants partagés sont particulièrement sensibles à ce problème, car les possibilités de bursting sont plus importantes, et l’impact est plus grand lorsque vous avez plus de locataires avec des modèles d’utilisation distincts.
Veillez à faire bon usage de l’élasticité et de l’échelle du cloud. Déterminez si vous devez utiliser une mise à l’échelle horizontale ou verticale, et utilisez la mise à l’échelle automatique pour gérer automatiquement les pics de charge. Testez votre solution pour comprendre son comportement sous différents niveaux de charge. Veillez à inclure les volumes de charge attendus en production, ainsi que la croissance attendue. Vous pouvez utiliser un service complètement managé, tel qu’Azure Load Testing, pour découvrir le comportement de votre application en situation de stress.
Antimodèle d’absence de mise en cache
On parle d’antimodèle Absence de mise en cache lorsque le niveau de performance de votre solution souffre du fait que la couche Application demande ou recalcule de manière répétée des informations qui pourraient être réutilisées d’une requête à l’autre. Si vous avez des données qui peuvent être partagées, soit entre les locataires, soit entre les utilisateurs d’un même locataire, il est probablement utile de les mettre en cache pour réduire la charge sur votre couche back-end ou couche de base de données.
Conservation de l’état inutile
Le corollaire de l’antimodèle Absence de mise en cache est que vous devez également éviter de stocker des états inutiles dans votre couche de calcul. Soyez explicite quant à l’emplacement où vous conservez l’état et au motif. Les couches Application ou frontale avec état peuvent réduire votre capacité à mettre à l’échelle. Les couches de calcul avec état requièrent généralement aussi une affinité de session, ce qui peut réduire votre capacité à équilibrer efficacement la charge du trafic entre les rôles de travail ou les nœuds.
Examinez les compromis pour chaque élément d’état que vous gérez dans votre couche de calcul, et voyez si cela a un impact sur votre capacité à mettre à l’échelle ou à croître en fonction de l’évolution des modèles de charge de travail de vos locataires. Vous pouvez également stocker l’état dans un cache externe, tel qu’Azure Cache pour Redis.
Contributeurs
Cet article est géré par Microsoft. Il a été écrit à l’origine par les contributeurs suivants.
Auteurs principaux :
- Dixit Arora | Ingénieur client senior, FastTrack for Azure
- John Downs | Ingénieur logiciel principal
Autres contributeurs :
- Arsen Vladimirskiy | Ingénieur client principal, FastTrack for Azure
Étapes suivantes
Examinez les aides spécifiques au service pour vos services de calcul :