Comment passer de 1 Ă 100 000 utilisateurs
De nombreuses startups sont passées par là : des foules de nouveaux utilisateurs sont enregistrées chaque jour et l'équipe de développement peine à prendre en charge le service.C'est un problÚme agréable, mais il y a peu d'informations claires sur le Web pour savoir comment faire évoluer avec précision une application Web de zéro à des centaines de milliers d'utilisateurs. Habituellement, il existe des solutions d'incendie ou l'élimination des goulots d'étranglement (et souvent les deux). Par conséquent, les gens utilisent des astuces assez stéréotypées pour transformer leur projet amateur en quelque chose de vraiment sérieux.Essayons de filtrer les informations et d'écrire la formule principale. Nous allons progressivement mettre à l'échelle notre nouveau site de partage de photos Graminsta de 1 à 100 000 utilisateurs.Nous noterons les actions spécifiques à entreprendre pour augmenter l'audience à 10, 100, 1000, 10 000 et 100 000 personnes.1 utilisateur: 1 voiture
Presque chaque application, quâil sâagisse dâun site Web ou dâune application mobile, comporte trois Ă©lĂ©ments clĂ©s:- API
- base de données
- client (application mobile ou site web lui-mĂȘme)
La base de donnĂ©es stocke des donnĂ©es persistantes. L'API sert les demandes pour et autour de ces donnĂ©es. Le client transfĂšre les donnĂ©es Ă l'utilisateur.J'en suis venu Ă la conclusion qu'il est beaucoup plus facile de parler de mise Ă l'Ă©chelle d'une application si, du point de vue de l'architecture, les entitĂ©s clientes et les API sont complĂštement sĂ©parĂ©es.Lorsque nous commençons Ă crĂ©er une application, les trois composants peuvent ĂȘtre exĂ©cutĂ©s sur le mĂȘme serveur. D'une certaine maniĂšre, cela nous rappelle notre environnement de dĂ©veloppement: un ingĂ©nieur exĂ©cute la base de donnĂ©es, l'API et le client sur le mĂȘme ordinateur.ThĂ©oriquement, nous pourrions le dĂ©ployer dans le cloud sur une instance de DigitalOcean Droplet ou AWS EC2, comme indiquĂ© ci-dessous:Cela dit, si le site a plus d'un utilisateur, il est presque toujours logique de mettre en Ă©vidence le niveau de la base de donnĂ©es.10 utilisateurs: prendre la base de donnĂ©es Ă un niveau distinct
La division d'une base de donnĂ©es en services gĂ©rĂ©s tels qu'Amazon RDS ou la base de donnĂ©es gĂ©rĂ©e par l'ocĂ©an numĂ©rique nous sera utile pendant longtemps. C'est un peu plus cher que l'auto-hĂ©bergement sur une seule machine ou une instance EC2, mais avec ces services, vous obtenez de nombreuses extensions utiles prĂȘtes Ă l'emploi qui vous seront utiles Ă l'avenir: sauvegardes multi-rĂ©gions, rĂ©pliques en lecture, sauvegardes automatiques et bien plus encore.Voici Ă quoi ressemble maintenant le systĂšme:100 utilisateurs: amener le client Ă un niveau distinct
Heureusement, notre application a vraiment aimĂ© les premiers utilisateurs. Le trafic devient plus stable, il est donc temps de dĂ©placer le client vers un niveau distinct. Il convient de noter que la sĂ©paration d' entitĂ©s est un aspect clĂ© de la construction d'une application Ă©volutive. Puisqu'une partie du systĂšme reçoit plus de trafic, nous pouvons le diviser de maniĂšre Ă contrĂŽler la mise Ă l'Ă©chelle du service en fonction de modĂšles de trafic spĂ©cifiques.C'est pourquoi j'aime reprĂ©senter le client sĂ©parĂ©ment de l'API. Il est donc trĂšs facile de parler de dĂ©veloppement pour plusieurs plates-formes: Web, Web mobile, iOS, Android, applications de bureau, services tiers, etc. Tous ne sont que des clients utilisant la mĂȘme API.Par exemple, maintenant, nos utilisateurs demandent le plus souvent de publier une application mobile. La sĂ©paration des entitĂ©s clientes et des API facilite la tĂąche.Voici Ă quoi ressemble le systĂšme:1000 utilisateurs: ajouter un Ă©quilibreur de charge
Ca va bien. Les utilisateurs de Graminsta tĂ©lĂ©chargent de plus en plus de photos. Le nombre d'inscriptions augmente Ă©galement. Notre seul serveur API a du mal Ă gĂ©rer tout le trafic. Besoin de plus de fer!L'Ă©quilibreur de charge est un concept trĂšs puissant. L'idĂ©e clĂ© est de placer l'Ă©quilibreur devant l'API et de rĂ©partir le trafic entre les instances de service individuelles. C'est la façon de faire Ă©voluer horizontalement, c'est-Ă -dire que nous ajoutons plus de serveurs avec le mĂȘme code, augmentant le nombre de requĂȘtes que nous pouvons traiter.Nous allons placer des Ă©quilibreurs de charge sĂ©parĂ©s devant le client Web et devant l'API. Cela signifie que vous pouvez exĂ©cuter plusieurs instances qui exĂ©cutent le code API et le code client Web. L'Ă©quilibreur de charge transmet les demandes au serveur le moins chargĂ©.Ici, nous obtenons un autre avantage important - la redondance. Lorsqu'une instance Ă©choue (peut-ĂȘtre des surcharges ou des plantages), nous en avons encore d'autres qui rĂ©pondent toujours aux demandes entrantes. Si une seule instance fonctionnait, en cas d'Ă©chec, tout le systĂšme tomberait.L'Ă©quilibreur de charge fournit Ă©galement une mise Ă l'Ă©chelle automatique. Nous pouvons le configurer pour augmenter le nombre d'instances avant la charge de pointe et rĂ©duire lorsque tous les utilisateurs dorment.Avec un Ă©quilibreur de charge, le niveau de l'API peut ĂȘtre mis Ă l'Ă©chelle Ă l'infini, nous ajoutons simplement de nouvelles instances Ă mesure que le nombre de demandes augmente.. , PaaS, Heroku Elastic Beanstalk AWS ( ). Heroku , - API. , Heroku â .
10 000 : CDN
Cela aurait peut-ĂȘtre dĂ» ĂȘtre fait dĂšs le dĂ©but. Le traitement des demandes et la prise de nouvelles photos commencent Ă charger trop nos serveurs.Ă ce stade, vous devez utiliser un service cloud pour stocker du contenu statique - images, vidĂ©os et bien plus encore (AWS S3 ou Digital Ocean Spaces). En gĂ©nĂ©ral, notre API doit Ă©viter de traiter des choses comme le tĂ©lĂ©chargement d'images et le tĂ©lĂ©chargement d'images sur un serveur.Un autre avantage de l'hĂ©bergement cloud est son CDN (dans AWS, ce module complĂ©mentaire est appelĂ© Cloudfront, mais de nombreux services de stockage cloud le proposent immĂ©diatement). CDN met automatiquement nos images en cache dans divers centres de donnĂ©es du monde entier.Bien que notre centre de donnĂ©es principal puisse ĂȘtre situĂ© dans l'Ohio, mais si quelqu'un demande une image au Japon, le fournisseur de cloud fera une copie et l'enregistrera dans son centre de donnĂ©es japonais. La prochaine personne Ă demander cette image au Japon la recevra beaucoup plus rapidement. Ceci est important lorsque nous travaillons avec des fichiers volumineux, comme des photos ou des vidĂ©os qui prennent beaucoup de temps Ă tĂ©lĂ©charger et Ă transmettre Ă travers la planĂšte entiĂšre.100 000 utilisateurs: mise Ă l'Ă©chelle du niveau de donnĂ©es
CDN a vraiment aidĂ©: le trafic augmente Ă pleine vitesse. La cĂ©lĂšbre blogueuse vidĂ©o, Maid Mobrick, vient de s'inscrire chez nous et a postĂ© son histoire, comme on dit. GrĂące Ă l'Ă©quilibreur de charge, le niveau d'utilisation du CPU et de la mĂ©moire sur les serveurs d'API est maintenu bas (dix instances d'API sont en cours d'exĂ©cution), mais nous commençons Ă obtenir de nombreux dĂ©lais d'attente pour les demandes ... d'oĂč viennent ces retards?AprĂšs un peu de fouille dans les mĂ©triques, nous voyons que le CPU sur le serveur de base de donnĂ©es est chargĂ© Ă 80-90%. Nous sommes Ă la limite.La mise Ă l'Ă©chelle de la couche de donnĂ©es est probablement la partie la plus difficile de l'Ă©quation. Les serveurs d'API servent des demandes sans Ă©tat, nous ajoutons donc simplement plus d'instances d'API. Mais avec la plupartles bases de donnĂ©es Ă©chouent. Nous discuterons des systĂšmes de gestion de bases de donnĂ©es relationnelles populaires (PostgreSQL, MySQL, etc.).Mise en cache
L'une des façons les plus simples d'augmenter les performances de notre base de donnĂ©es est d'introduire un nouveau composant: le niveau de cache. La mĂ©thode de mise en cache la plus courante consiste Ă stocker des enregistrements de valeurs-clĂ©s dans la RAM, tels que Redis ou Memcached. La plupart des clouds ont une version gĂ©rĂ©e de ces services: Elasticache sur AWS et Memorystore sur Google Cloud.Le cache est utile lorsqu'un service effectue de nombreux appels rĂ©pĂ©tĂ©s Ă la base de donnĂ©es pour obtenir les mĂȘmes informations. En fait, nous accĂ©dons Ă la base de donnĂ©es une seule fois, enregistrons les informations dans le cache - et n'y touchons plus.Par exemple, dans notre service Graminsta, chaque fois que quelqu'un accĂšde Ă la page de profil de l'Ă©toile Mobric, le serveur API demande des informations Ă son profil dans la base de donnĂ©es. Cela arrive encore et encore. Ătant donnĂ© que les informations de profil de Mobrick ne changent pas Ă chaque demande, elles sont idĂ©ales pour la mise en cache.Nous mettrons en cache les rĂ©sultats de la base de donnĂ©es dans Redis par clĂ© user:id
avec une pĂ©riode de validitĂ© de 30 secondes. Maintenant, quand quelqu'un entre dans le profil de Mobrick, nous vĂ©rifions d'abord Redis, et si les donnĂ©es sont lĂ , nous les transfĂ©rons simplement directement de Redis. Maintenant, les requĂȘtes sur le profil le plus populaire sur le site ne chargent pratiquement pas notre base de donnĂ©es.Un autre avantage de la plupart des services de mise en cache est qu'ils sont plus faciles Ă faire Ă©voluer que les serveurs de base de donnĂ©es. Redis dispose d'un mode de cluster Redis Cluster intĂ©grĂ©. Comme un Ă©quilibreur de charge1, il vous permet de distribuer le cache Redis sur plusieurs machines (sur des milliers de serveurs, si nĂ©cessaire).Presque toutes les applications Ă grande Ă©chelle utilisent la mise en cache; cela fait partie intĂ©grante de l'API rapide. Traitement des demandes plus rapide et code plus productif - tout cela est important, mais sans cache, il est presque impossible d'adapter le service Ă des millions d'utilisateurs.Lecture de rĂ©pliques
Lorsque le nombre de requĂȘtes vers la base de donnĂ©es a considĂ©rablement augmentĂ©, nous pouvons faire une chose de plus: ajouter des rĂ©pliques en lecture dans le systĂšme de gestion de base de donnĂ©es. En utilisant les services gĂ©rĂ©s dĂ©crits ci-dessus, cela peut ĂȘtre fait en un seul clic. La rĂ©plique en lecture restera pertinente dans la base de donnĂ©es principale et est disponible pour les instructions SELECT.Voici notre systĂšme maintenant:Actions supplĂ©mentaires
Au fur et Ă mesure que l'application Ă©volue, nous continuerons de sĂ©parer les services pour les adapter indĂ©pendamment. Par exemple, si nous commençons Ă utiliser Websockets, il est logique d'extraire le code de traitement Websockets dans un service distinct. Nous pouvons le placer sur de nouvelles instances derriĂšre notre propre Ă©quilibreur de charge, qui peut Ă©voluer vers le haut et vers le bas en fonction des connexions Websockets ouvertes et quel que soit le nombre de requĂȘtes HTTP.Nous continuons Ă©galement Ă lutter contre les restrictions au niveau de la base de donnĂ©es. C'est Ă ce stade que le moment est venu d'Ă©tudier le partitionnement et le sharding de la base de donnĂ©es. Les deux approches nĂ©cessitent des frais supplĂ©mentaires, mais elles vous permettent de faire Ă©voluer la base de donnĂ©es presque Ă l'infini.Nous voulons Ă©galement installer un service de surveillance et d'analyse comme New Relic ou Datadog. Cela permettra d'identifier les requĂȘtes lentes et de comprendre oĂč des amĂ©liorations sont nĂ©cessaires. Ă mesure que nous Ă©voluons, nous voulons nous concentrer sur la recherche de goulots d'Ă©tranglement et leur rĂ©solution - en utilisant souvent certaines idĂ©es des sections prĂ©cĂ©dentes.Sources
Ce message est inspirĂ© de l'un de mes messages prĂ©fĂ©rĂ©s Ă haute Ă©volutivitĂ© . Je voulais concrĂ©tiser un peu l'article pour les premiĂšres Ă©tapes des projets et le dĂ©tacher d'un fournisseur. N'oubliez pas de lire si vous ĂȘtes intĂ©ressĂ© par ce sujet.Notes de bas de page
- Malgré les similitudes en termes d'équilibrage de charge sur plusieurs instances, l'implémentation de base du cluster Redis est trÚs différente de l'équilibreur de charge. [rendre]

Source: https://habr.com/ru/post/undefined/
All Articles