Elasticité des applications (2/2)

Dans notre dernier post, nous avons expliqué la notion d’élasticité, en tant que capacité à déplacer des ressources au sein d’une infrastructure virtuelle afin de répondre avec la meilleure réactivité possible aux demandes métier et aux pics d’activités, ces derniers pas toujours prévisibles.

Mais il ne s’agit pas seulement de pouvoir ‘gonfler’ l’infrastructure en ajoutant les ressources qui s’avèrent nécessaires, sinon – et surtout – de pouvoir ‘dégonfler’ celle-ci en réaffectant ces ressources par ailleurs. A l’image d’un ballon, plus l’infrastructure est élastique, plus elle est facile et rapide à gonfler et dégonfler.

Encore faut-il que les applications veulent bien s’y prêter.

 

L’élasticité d’une application suppose :

  • La scalabilité : maintenir la performance des applications lorsque augmente le nombre d’utilisateurs – et généralement par conséquence le volume de données
  • La capacité à libérer les ressources lorsque la charge décroît.

On distingue deux types de scalabilité :

  • La scalabilité horizontale consiste à distribuer une application sur différentes machines. Par exemple, vous ajoutez des instances supplémentaires de votre serveur d’application et utilisez un load-balanceur pour répartir la charge.
  • La scalabilité verticale consiste à ajouter de la capacité (mémoire, CPU, disque dur) sur la machine qui héberge votre application.

Scabilité horizontale

La scalabilité horizontale n’est pas très élastique, puisqu’elle suppose d’ajouter manuellement des instances de briques d’architecture qui resteront largement sous-utilisées en l’absence de pics de charge. Autrement dit, vous gonflez le ballon mais ne savez pas le dégonfler. C’est pourtant le cas que l’on rencontrera le plus fréquemment. Ce n’est pas vraiment dynamique.

Et maintenir un infrastructure basée sur la redondance des différentes briques de l’architecture applicative aboutit au cas précédent : une infrastructure surdimensionnée afin de faire face aux pics d’activité, mais dont on n’utilise la capacité qu’à 10 ou 20%. Autant rester sur une instrastructure phyique.

Scabilité verticale

La scalabilité verticale est elle beaucoup plus élastique. Vous installez votre application sur une machine virtuelle dont elle prendra 50% des ressources en régime normal, au sein d’un serveur hébergeant d’autres machines virtuelles avec des applications moins sujettes à variation de charge. Si survient un pic d’activité imprévu et même violent, la machine virtuelle pourra emprunter des ressources aux machines voisines sur le même serveur. La possibilité d’emprunter ainsi de la mémoire est d’ailleurs connue sous le nom de ‘ballooning’ (pour VMWare). Une fois le pic de charge passé, la machine virtuelle libèrera les ressources empruntées pour les restituer à ses voisines. Tout ceci dynamiquement, avec le moins de saturation et de contention possible.

Mais la scalabilité verticle atteint rapidement ses limites: vous ne pouvez pas augmenter indéfiniment la puissance CPU ou la performance I/O d’un disque dur. Vous pouvez gonfler et dégonfler le ballon, mais dans une certaine limite.

Elasticité du Cloud

Toute application gagnera en élasticité en allant dans le Cloud.

Par exemple, certains traitements consommateurs de mémoire, comme la création d’un objet, ne doivent pas être effectués au sein d’une boucle. Nombre de boucles servent à réaliser des traitements sur les données d’une table. Plus la table contient de données, plus le nombre d’itérations de la boucle sera élevé, plus la création d’objets et la consommation de mémoire correspondante sera élevé. Plus le nombre d’utilisateurs sera important, plus le serveur d’application effectuera ces traitements et aura besoin de mémoire.

C’est un exemple typique d’une application avec une faible scalabilité que l’on contournera en ajoutant ‘élastiquement’ de la mémoire lors des pics d’activité.

Autre exemple : vous load-balancez 2 serveurs d’applications sur 2 machines virtuelles. Vous avez donc 2 copies du même software montées en mémoire. Si l’hyperviseur est capable de détecter ces ensembles de mémoire identiques, il peut mettre en place un mécanisme de partage mémoire de telle sorte qu’un seul espace mémoire sera utilisé et accédé par les 2 machines virtuelles, de manière transparente. Vous économisez ainsi de la mémoire.

Elasticité des applications

Certaines techniques de programmation vont permettre de rendre une application plus ou moins élastique. La première et la plus souvent citée est de rendre l’application la plus stateless possible. Qu’est ce que cela veut dire ?

Pour faire simple, une application stateful garde en mémoire les données nécessaires à la session utilisateur et à son contexte. La session est gardée sur le même serveur le temps que l’utilisateur est connecté : il n’est pas possible de transférer cette session – les données gardées en mémoire – sur un autre serveur.

Imaginons donc un site marchand avec une forte activité entre 9 heures et 17 heures, correspondant à 10 000 utilisateurs qui se répartissent sur 10 serveurs. Si l’application est stateful, toutes les données sont stockées en mémoire, y compris celles identifiant l’utilisateur et la mémoire ne sera libérée que lorsque celui-ci quitte le site en se déconnectant. Si 10% des utilisateurs oublient de se déconnecter, ou si l’activité tombe à 1 000 utilisateurs hors de la période de pointe, on gardera alors 1 000 sessions en mémoire… réparties sur les 10 serveurs. Autrement dit, l’application utilisera 10% des 10 serveurs là où 1 seul serveur serait suffisant.

Si maintenant l’application est complètement stateless, la session n’est pas gardée en mémoire et donc n’est pas attachée à un serveur. Même si 10% des sessions restent actives, il sera possible de libérer les serveurs au fur et à mesure que décroît l’activité, pour ne garder qu’un seul serveur occupé à 100% (ou plutôt 2 serveurs occupés à 50%).

Il est difficile de programmer des applications complètement stateless, puisqu’il faut bien stocker les données quelque part, et si ce n’est en mémoire, ce sera alors en base de données, de manière au moins temporaire. Or un accès en base de données est plus coûteux en performance qu’un accès mémoire. On va donc s’attacher à concevoir l’application en différents modules ou différentes sous-applications, certaines stateless, d’autres stateful.

Par exemple, l’application qui gère le panier de l’utilisateur gagnera à être programmé en mode ‘stateful’ avec plusieurs avantages :

  • Ce sont les données qui sont le plus accédées et modifiées durant la session, donc pour lesquelles la meilleure performance est requise : rien de pire que devoir attendre 10 secondes chaque fois que vous ajoutez un nouvel article dans votre panier, vous quitterez bien vite le site.
  • Le panier a une durée de vie limitée : généralement 30 à 60 minutes. Si un utilisateur reste connecté sans mettre à jour son panier, la session sera supprimée de la mémoire à l’issue de ce délai, ce qui permettra de ‘dégonfler’ la mémoire. Ceci règle le problème des 10% d’utilisateurs qui oublient de se déconnecter.

Les autres données, telles que celles identifiant l’utilisateur, peuvent être géré par un module stateless avec une table temporaire. Remarque importante : on voit également à travers cet exemple qu’il importe de penser en termes de durée de vie de chaque module et de programmer celle-ci à travers un time-out.

L’asynchronisme est un autre mécanisme qui favorise l’élasticité. Le traitement de votre panier sur un site marchand ne se termine pas avec la finalisation de votre achat et son paiement : il faut ensuite utiliser ses données pour préparer votre colis, sa livraison, l’enregistrer en comptabilité, etc… Mais tous ces traitements ne sont pas urgents et peuvent être réalisés lorsque les serveurs sont moins occupés, durant la nuit par exemple. On va donc s’attacher à découpler le front-end – le site marchand – en envoyant un message asynchrone au back-end, les applications logistiques et comptables, avec les données de votre commande pour que celles-ci soient processées durant la période de moindre activité, sur les serveurs inactifs avec les ressources libérées.

L’obstacle principal à l’élasticité des applications réside à mon avis au niveau de la base de données, certainement la plus difficile à ‘scaler’ horizontalement. Les pistes actuelles en matière de gestion de la persistence semblent promouvoir là encore une certaine modularité qui permette de distribuer les informations sur différentes bases de données.

Enfin, je pense que la réalisation d’applications élastiques destinées au Cloud va introduire de profonds changements méthodologiques au niveau des cycles de vie de projet, car une meilleure intégration entre les équipes de développement, de QA et de production me paraît inéluctable. Une sorte de fusion entre ITIL et Agile.

La préoccupation principale des équipes de développement et de QA est de délivrer en temps et en heure des applications de la meilleure qualité possible, pas la consommation de ressources. Sauf à disposer d’équipes dédiées à la réalisation d’applications virtualisées, la prise en compte de la consommation des ressources ou de l’élasticité n’est pas à l’ordre du jour. Le seul point sur lequel ces deux mondes se rencontrent concerne la disponibilité de service et donc les accords de service (Service Level Agreement).

Donc je suis convaincu que chaque développeur va devoir ajouter des compétences en matière de virtualisation à son CV et que chaque société de services va devoir se doter de ces mêmes compétences et méthodologies afin de développer des applications élastiques.

Le Cloud est en train de sortir des salles machines. Tenez vous prêts.

Ce article est également disponible en Leer este articulo en castellano et Read that post in english.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *