Mise à l'échelle de votre application Web : étapes de base
Publié: 2022-09-13Il ne suffit pas de créer des applications pour votre entreprise, vous devez les optimiser. Un moyen efficace consiste à mettre à l'échelle. Dans cet article, vous découvrirez l'optimisation du code, l'optimisation de l'architecture et comment créer des applications Web évolutives en général.
Optimisation
Gearheart suggère de vous poser les questions suivantes :
- les requêtes en base de données sont-elles optimales (analyse EXPLAIN, utilisation d'index) ?
- les données sont-elles stockées correctement (SQL vs NoSQL) ?
- la mise en cache est-elle utilisée ?
- pas de requêtes inutiles au FS ou à la base de données ?
- les algorithmes de traitement des données sont-ils optimaux ?
- les paramètres d'environnement sont-ils optimaux : Apache/Nginx, MySQL/PostgreSQL, PHP/Python ?
Chacune de ces questions pouvant faire l'objet d'un article séparé, leur examen détaillé dans le cadre de cet article est manifestement excessif. Il est important de comprendre qu'avant de commencer à faire évoluer une application, il est hautement souhaitable d'optimiser son travail autant que possible - en fait, il est alors possible qu'aucune mise à l'échelle ne soit nécessaire.
Mise à l'échelle
Supposons que vous ayez déjà optimisé votre application, mais qu'elle ne soit toujours pas capable de gérer la charge. Dans ce cas, la solution évidente consiste à répartir l'application sur plusieurs hôtes afin d'augmenter les performances globales de l'application en augmentant les ressources disponibles. Cette approche est officiellement appelée « mise à l'échelle » de l'application. Plus précisément, la scalabilité est la capacité d'un système à augmenter ses performances en augmentant la quantité de ressources dont il dispose.
Il existe deux types d'évolutivité : verticale et horizontale. L'évolutivité verticale implique l'augmentation des performances des applications en ajoutant des ressources (processeur, mémoire, disque) au sein d'un nœud (hôte). La mise à l'échelle horizontale est typique des applications distribuées et implique l'augmentation des performances de l'application en ajoutant un autre nœud.
Il est clair que le moyen le plus simple est une simple mise à niveau matérielle (processeur, mémoire, disque) - c'est-à-dire une mise à l'échelle verticale. De plus, cette approche ne nécessite aucune modification de l'application. Cependant, la mise à l'échelle verticale atteint rapidement sa limite, après quoi le développeur et l'administrateur n'ont d'autre choix que de passer à la mise à l'échelle horizontale de l'application.
Architecture des applications
La plupart des applications web sont a priori distribuées, car leur architecture peut être divisée en au moins trois couches : web-serveur, logique métier (application), données (base de données, statique).
Chacune de ces couches peut être mise à l'échelle. Donc, si votre système a une application et une base de données résidant sur le même hôte, la première étape devrait certainement être de les séparer sur des hôtes différents.
Le goulot d'étranglement
En procédant à la mise à l'échelle du système, la première chose à faire est de déterminer laquelle des couches est le « goulot d'étranglement », c'est-à-dire la plus lente que le reste du système. Pour commencer, vous pouvez utiliser des utilitaires triviaux comme top (htop) pour évaluer la consommation CPU/mémoire et df, iostat pour évaluer la consommation disque. Cependant, il est souhaitable de fournir un hôte séparé avec une émulation de charge de combat (utilisant AB ou JMeter), sur lequel vous pouvez profiler l'application à l'aide d'utilitaires tels que xdebug, oprofile, etc. Vous pouvez utiliser des utilitaires comme pgFouine pour identifier les requêtes de base de données étroites (bien sûr, il est préférable de le faire en fonction des journaux du serveur de combat).
Cela dépend généralement de l'architecture de l'application, mais en général, les candidats les plus probables à un goulot d'étranglement sont la base de données et le code. Si votre application gère beaucoup de données utilisateur, le goulot d'étranglement est probablement le stockage statique.
Mise à l'échelle de la base de données
Comme mentionné ci-dessus, le goulot d'étranglement des applications modernes est souvent la base de données. Les problèmes avec cela sont généralement divisés en deux catégories : les performances et la nécessité de stocker une grande quantité de données.
Vous pouvez réduire la charge sur la base de données en la divisant en plusieurs hôtes. Il existe une difficulté aiguë de synchronisation entre eux, qui peut être résolue en mettant en oeuvre le schéma maître/esclave avec réplication synchrone ou asynchrone. Pour PostgreSQL, vous pouvez utiliser Slony-I pour la réplication synchrone et PgPool-II ou WAL (9.0) pour la réplication asynchrone. Pour résoudre le problème de séparation des requêtes de lecture et d'écriture, ainsi que l'équilibrage de la charge entre les esclaves, vous pouvez configurer une couche d'accès à la base de données spéciale (PgPool-II).
Le souci de stocker de grandes quantités de données dans le cas de bases de données relationnelles peut être résolu en partitionnant ("partitionnement" dans PostgreSQL), ou en déployant la base de données sur une base de données distribuée comme Hadoop DFS.
Vous pouvez en savoir plus sur les deux solutions dans l'excellent livre sur la configuration de PostgreSQL.
1.Cependant, pour stocker de grandes quantités de données, la meilleure solution est le sharding, qui est un avantage inhérent à la plupart des bases de données NoSQL (par exemple, MongoDB).
2. De plus, les bases de données NoSQL fonctionnent en général plus rapidement que leurs frères SQL en raison du manque de temps système pour l'analyse/l'optimisation de la requête, la vérification de l'intégrité de la structure des données, etc. Le sujet de la comparaison des bases de données relationnelles et NoSQL est également assez vaste et mérite un article séparé.
3. Il convient de noter séparément l'expérience de Facebook, qui utilise MySQL sans sélections JOIN. Cette stratégie leur permet de faire évoluer la base de données beaucoup plus facilement, tout en transférant la charge de la base de données au code, qui, comme cela sera décrit ci-dessous, évolue plus facilement que la base de données.
Mise à l'échelle du code
- La complexité de la mise à l'échelle du code dépend du nombre de ressources partagées dont vos hôtes ont besoin pour exécuter votre application. S'agira-t-il uniquement de sessions ou devrez-vous partager des caches et des fichiers ? Dans tous les cas, la première chose à faire est d'exécuter des copies de l'application sur plusieurs hôtes avec le même environnement.
- Ensuite, vous devez configurer l'équilibrage de charge/requête entre ces hôtes. Vous pouvez le faire à la fois sur TCP (HAProxy), HTTP (nginx) ou DNS.
- L'étape suivante, a mentionné Gearheart, consiste à rendre les fichiers statiques, le cache et les sessions d'application Web disponibles sur chaque hôte. Pour les sessions, vous pouvez utiliser un serveur fonctionnant sur le réseau (par exemple, Memcached). En tant que serveur de cache, il est logique d'utiliser le même Memcached, mais sur un hôte différent, bien sûr.
- Les fichiers statiques peuvent être montés à partir d'un stockage de fichiers partagé via NFS/CIFS ou à l'aide de FS distribués (HDFS, GlusterFS, Ceph).
Il est également possible de stocker des fichiers dans une base de données (par exemple, Mongo GridFS), résolvant ainsi le problème de disponibilité et d'évolutivité (en tenant compte du fait que pour la base de données NoSQL, le problème d'évolutivité est résolu par le sharding).
A noter séparément, la question du déploiement sur plusieurs hôtes. Comment s'assurer que l'utilisateur en cliquant sur "Mettre à jour" ne voit pas différentes versions de l'application ? La solution la plus simple, à mon avis, serait d'exclure de l'équilibreur de charge de configuration (serveur Web) les hôtes qui ne sont pas mis à jour et de les activer séquentiellement au fur et à mesure des mises à jour. Vous pouvez également lier les utilisateurs à des hôtes spécifiques par cookie ou IP. Si la mise à jour nécessite des modifications importantes de la base de données, le moyen le plus simple consiste à fermer temporairement le projet.