Quel est le meilleur moyen de concevoir un site Web hautement évolutif?


35

Pour les sites Web nécessitant une grande évolutivité, tels que les réseaux sociaux tels que Facebook, quel est le meilleur moyen de concevoir le site Web?

  1. Devrais-je avoir un service Web sur lequel le site interroge pour obtenir les données dont il a besoin?

    ou

  2. Le site doit-il interroger directement les bases de données? (peut être fait en utilisant des constructions de langage intégrées pour remplir automatiquement les tableaux, etc.).

Je pense que le service Web est le meilleur concept car il offre un accès centralisé aux données et que des éléments tels que la mise en cache, etc. deviennent beaucoup plus faciles à contrôler, mais qu’en pensent les autres?


Il y a aussi la question de quelle architecture utiliser (comme MVC ou similaire).
Ivan

Sans en savoir plus sur ce que vous allez lancer au juste, il est très difficile de donner la réponse, mais gardez à l’esprit les "services Cloud", probablement que votre application s’intègre dans une sorte d’application SaaS. (C'est centralisé).
deepcell

De manière générale, dirais-je, rien de particulier à l'esprit ..
Daniel

1
Construisez-le dans le «nuage» et passez beaucoup de temps à lire HighScalability.com.
Evan Plaice

Réponses:


37

Wow, c'est une question simple, à laquelle un grand nombre de réponses possibles. La partie la plus explicite de votre question demande s'il est plus évolutif de s’interfacer directement avec votre base de données ou via un service Web. Cette réponse est simple: interrogez directement la base de données. Le fait de passer par le service Web ajoute beaucoup de temps de latence, ce qui est totalement inutile pour le code fonctionnant derrière un pare-feu (dans l’ensemble). Un service Web, par exemple, nécessite un composant pour recevoir une demande, la désérialiser, interroger la base de données, sérialiser une réponse et la renvoyer. Donc, si votre code fonctionne entièrement derrière un pare-feu, évitez les problèmes et interrogez directement la base de données.

Rendre un site Web évolutif va toutefois bien au-delà de la question que vous avez posée initialement. Alors pardonnez-moi si je suis sur une tangente ici, mais j'ai pensé que cela pourrait être utile étant donné que vous avez mentionné Facebook en particulier.

Je vous recommanderais de lire le travail et les outils construits par Brad Fitzpatrick (fondateur de LiveJournal et maintenant chez Google). Lorsque j'ai travaillé avec lui à Six Apart, voici certaines des choses que j'ai apprises de lui et de l'architecture de LiveJournal qui l'a rendu si évolutif.

  1. Utilisez des tables de base de données étroites plutôt que larges . Ce qui était fascinant, c’était d’apprendre ce qui motivait cette architecture, qui créait un système facile et rapide à utiliser.mis à niveau. Si vous utilisez des tables étendues, ou des tables pour lesquelles chaque champ ou propriété est une colonne de la table, le moment venu de mettre à niveau le schéma de base de données, par exemple en ajoutant une nouvelle colonne, le système devra alors verrouiller la table pendant que le schéma le changement est mis en œuvre. En cas de fonctionnement à grande échelle, cela signifierait qu'une simple modification du schéma de la base de données pourrait entraîner une panne importante de la base de données. Ce qui craint évidemment. D'autre part, une table étroite stocke simplement chaque propriété individuelle associée à un objet sous la forme d'une seule ligne dans la base de données. Par conséquent, lorsque vous souhaitez ajouter une nouvelle colonne à la base de données, il vous suffit d'insérer des enregistrements dans une table, ce qui est une opération non verrouillable. Ok, c’est un peu d’arrière-plan. Voyons comment ce modèle se traduit dans un système fonctionnel tel que LiveJournal.

    Supposons que vous souhaitiez charger les 10 dernières entrées de journal sur le blog d'une personne et supposons que chaque entrée de journal possède dix propriétés. Dans une disposition de table large classique, chaque propriété serait corrélée à une colonne sur une table. Un utilisateur interroge ensuite la table une fois pour récupérer toutes les données dont il a besoin. La requête renvoie 10 lignes et chaque ligne contient toutes les données nécessaires (par exemple, les entrées SELECT * FROM ORDER BY date LIMIT 10). Dans une disposition de table étroite, les choses sont toutefois légèrement différentes. Dans cet exemple, il y a en fait deux tables: la première table (la table A) stocke les critères simples que l'on voudrait rechercher, par exemple l'id de l'entrée, l'id de l'auteur, la date de l'entrée, etc. Une seconde table (table B) stocke ensuite toutes les propriétés associées à une entrée. Cette deuxième table a trois colonnes: entry_id, key et value. Pour chaque ligne de la table A, il y aurait 10 lignes dans la table B (une ligne pour chaque propriété). Par conséquent, pour extraire et afficher les dix dernières entrées, il vous faudrait 11 requêtes. La première requête vous donne la liste des ID d'entrées, puis les dix requêtes suivantes extraient les propriétés associées à chacune des entrées renvoyées dans la première requête.

    "Sainte moly!" vous dites, "comment sur Terre peut-il être plus évolutif?!" C'est totalement contre-intuitif, n'est-ce pas? Dans le premier scénario, nous avions juste une requête de base de données, mais dans la deuxième solution "plus évolutive", nous avons 11 requêtes de base de données. Ça n'a aucun sens. La réponse à cette question repose entièrement sur le point suivant.

  2. Utilisez Memcache généreusement. Au cas où vous ne le sauriez pas, memcache est un système de mise en cache réseau distribué, sans état, à faible latence. Il est utilisé par Facebook, Google, Yahoo et pratiquement tous les sites Web populaires et évolutifs de la planète. Brad Fitzpatrick l'a inventé en partie pour aider à compenser la surcharge de la base de données inhérente à la conception d'une base de données à tables étroites. Jetons un coup d'oeil au même exemple que discuté dans # 1 ci-dessus, mais cette fois, introduisons memcache.

    Commençons lorsqu'un utilisateur visite pour la première fois une page et que rien ne se trouve dans le cache. Vous commencez par interroger la table A qui renvoie les identifiants des 10 entrées que vous souhaitez afficher sur la page. Pour chacune de ces entrées, vous interrogez ensuite la base de données pour récupérer les propriétés associées à cette entrée, puis l'utilisation de ces propriétés constitue un objet avec lequel votre code peut s'interfacer (par exemple, un objet). Vous cachez ensuite cet objet (ou une forme sérialisée de cet objet) dans memcache.

    La deuxième fois que quelqu'un charge la même page, vous commencez de la même manière: en interrogeant le tableau A pour connaître la liste des ID d'entrée que vous souhaitez afficher. Pour chaque entrée, vous allez d'abord dans memcache et dites: "avez-vous l'entrée #X dans le cache?" Si oui, alors memcache vous renvoie l'objet d'entrée. Sinon, vous devez interroger à nouveau la base de données pour en extraire les propriétés, constituer l'objet et le cacher dans memcache. La plupart du temps, la deuxième fois que quelqu'un visite la même page, il n'y a qu'une requête dans la base de données. Toutes les autres données sont ensuite extraites directement de memcache.

    En pratique, ce qui a fini par se produire dans LiveJournal est que la plupart des données du système, en particulier les moins volatiles, ont été mises en cache dans memcache et que les requêtes supplémentaires de la base de données nécessaires à la prise en charge du schéma de table étroit ont été complètement compensées.

    Cette conception a fait résoudre le problème lié à l' assemblage d' une liste des postes associés à tous vos amis dans un ruisseau, ou « mur » beaucoup, beaucoup plus facile.

  3. Ensuite, envisagez de partitionner votre base de données. Le modèle présenté ci-dessus fait apparaître un autre problème: vos tables étroites auront tendance à être très grandes / longues. Et plus ces tables ont de lignes, plus les autres tâches administratives deviennent difficiles. Pour compenser cela, il peut être judicieux de gérer la taille de vos tables en les partitionnant de façon à ce que les clusters d'utilisateurs soient desservis par une base de données et qu'un autre groupe d'utilisateurs soit desservi par une base de données distincte. Cela répartit la charge sur la base de données et optimise l'efficacité des requêtes.

  4. Enfin, vous avez besoin d'index géniaux. La rapidité de vos requêtes dépendra en grande partie de la qualité de l'indexation des tables de votre base de données. Je ne passerai pas trop de temps à discuter de ce qu'est un index, sauf à dire que c'est un peu comme un système de catalogue de cartes géant qui permet de trouver plus efficacement des aiguilles dans une botte de foin. Si vous utilisez mysql, je vous recommande d'activer le journal de requête lent pour surveiller les requêtes dont le traitement prend beaucoup de temps. Lorsqu'une requête apparaît sur votre radar (par exemple parce qu'elle est lente), déterminez quel index vous devez ajouter au tableau pour l'accélérer.

"Merci pour tout ce bon arrière-plan, mais bon Dieu, c'est beaucoup de code que je vais devoir écrire."

Pas nécessairement. De nombreuses bibliothèques ont été écrites pour faciliter l’interface avec memcache. Encore d'autres bibliothèques ont codifié le processus complet décrit ci-dessus; Data :: ObjectDriver in Perl est une telle bibliothèque. Pour les autres langues, vous devrez faire vos propres recherches.

J'espère que vous avez trouvé cette réponse utile. Ce que j’ai constaté le plus souvent, c’est que l’évolutivité d’un système dépend souvent de moins en moins du code, et de plus en plus d’une stratégie / conception technique saine de stockage et de gestion des données.


3
+1 J'aime vraiment ce Wow, c'est une question simple, à laquelle un grand nombre de réponses possibles.
Pankaj Upadhyay

1
Je suis complètement en désaccord avec 'interroger directement la base de données'. Vous parlez de partitionner la base de données pour obtenir des performances lorsqu'il serait plus facile de mettre en œuvre une architecture à maître unique et plusieurs esclaves avec une interface API. Le découplage de la base de données de l'application présente l'avantage de permettre à la couche API de distribuer les demandes à votre guise. L'API est une abstraction qui vous permet de modifier l'implémentation sous-jacente et / ou de réutiliser les données sans interrompre l'application.
Evan Plaice

1
(suite) La sérialisation ajoutera toujours une surcharge, mais uniquement dans la couche API, qui sera probablement constituée de plusieurs instances s'exécutant simultanément. Si vous êtes inquiet au sujet des vitesses de transfert sur le réseau, convertissez-le au format JSON. Il sera probablement compressé avec gzip de toute façon. Les gains de performance les plus faciles peuvent être trouvés lorsque le travail est transféré du serveur au client. La question importante à poser est la suivante: préféreriez-vous répartir les requêtes au sein de l’application ou au niveau du serveur? Lequel est le plus facile à dupliquer?
Evan Plaice

1
@EvanPlaice - Excellents avantages pour la réutilisation et la modification de la mise en œuvre de la logique de service lors de l'utilisation de services. En outre, l'infrastructure de cache peut également être utilisée par les services au lieu d'appels directs à la base de données.
Ashish Gupta

1
@AshishGupta Exactement, la seule différence entre le partitionnement des données et un service distinct est ce que l'utilisateur reçoit. Assemblez plutôt le contenu HTML + sur le serveur. L'utilisateur reçoit les données et le html séparément et le navigateur client gère le réassemblage. Avec les données en tant que service séparé, il devient également possible de les rendre disponibles pour des applications mobiles ou d'autres clients non basés sur le Web (par exemple les applications smart tv).
Evan Plaice le

13

Pour les sites Web nécessitant une grande évolutivité, tels que les réseaux sociaux tels que Facebook, quel est le meilleur moyen de concevoir le site Web?

Mesure.

Je penserais que le ...

Mauvaise politique.

La mesure réelle est requise.


Mesures quantitatives FTW.
Bhagyas

1
Ok ... alors après la mesure?
Pacerier

9

L’évolutivité n’est pas fonction de stratégies d’implémentation spécifiques, mais plutôt de la conception de l’architecture de votre application, de sorte que la couche d’accès aux données puisse évoluer sans refactorisation ni réécriture massives.

Une technique importante pour la construction d’un système évolutif consiste à comprendre vos besoins d’accès aux données de haut niveau et à établir un contrat d’interface autour de ces derniers. Par exemple, vous devrez peut-être obtenir un utilisateur ou répertorier les 50 photos les plus récemment publiées par un utilisateur .

Vous n'avez pas nécessairement besoin d'un canal réseau entre la logique métier de votre application et la logique d'accès aux données; un appel de méthode indirection avec une méthode par opération logique ferait bien de commencer.

Rendez ces méthodes d’accès aux données aussi simples que possible. Il est très difficile de prédire quels seront les problèmes de performances tant que votre application ne respectera pas les habitudes d'utilisation réelles et que vous ne collecterez des données sur les goulots d'étranglement.

En disposant d'une interface d'accès aux données bien définie, vous pouvez faire évoluer la mise en œuvre de votre accès aux données sans apporter de modifications générales à l'ensemble de votre application. Vous pouvez également décider de basculer vers une architecture de service Web transparente à votre logique métier.

La plupart des réponses ci-dessus donnent de bons conseils sur la manière de procéder une fois que vous avez découvert vos goulots d'étranglement, mais si vous les appliquez trop tôt, vous risquez de vous perdre dans la complexité de votre code avant de savoir si cette complexité est même requise.


4

Développez un site Web simple et laissez-le atteindre un certain niveau de trafic. Au fil des lignes, vous apprendrez à créer des sites Web évolutifs.

Tant que vous n’êtes pas confronté au problème, vous ne pouvez pas penser à une solution .

Faites-moi confiance une fois que vous avez le site en marche et que vous devez faire face à une mise à l'échelle, vous saurez certainement comment le faire. :-)


Bonne citation !!!!!!!!!!
AmirHossein

2

Il est généralement admis que les applications Web devraient être conçues avec trois niveaux par défaut: les couches Web (présentation), application et base de données. Cette division est due aux différentes exigences au niveau de chaque couche - typiquement un accès / stockage de qualité sur disque pour la base de données, un processeur / mémoire élevé au niveau de la couche application et une dispersion importante de la bande passante externe / mémoire / géographique au niveau de la couche Web. Les couches application / base de données sont souvent fusionnées en une seule couche jusqu’à beaucoup plus tard dans le cycle de vie de l’application, car les machines de base de données ont souvent tendance à être des serveurs énormes pouvant également être construits pour gérer la charge initiale des applications.

Le nombre spécifique de couches et l'architecture appropriée pour votre application ne doivent pas nécessairement correspondre à ce modèle ni à aucun autre.

Prévoyez d'avoir besoin de mesurer et de surveiller toutes les activités de votre système. Commencez par une conception à deux ou trois niveaux et concentrez-vous sur les parties qui, au fur et à mesure que vous les construisez, nécessiteront le plus de ressources. Laissez l'application en cours guider votre conception, à ce niveau. Plus vous collectez d'informations, plus elles sont précises et détaillées, meilleures sont les décisions que vous pouvez prendre pour concevoir l'application au fur et à mesure de sa croissance.

Choisissez un cadre et une architecture qui, ultérieurement, vous permettront de faire pivoter / apporter les modifications requises aussi rapidement et sans douleur possible. Même si votre accès aux données / stockage / traitement et le traitement des applications sont exécutés dans le même exécutable, par exemple, s'ils sont correctement factorisés, il ne sera pas aussi difficile de les scinder ultérieurement en deux couches.


2

Toute étape supplémentaire dans la connexion à la base de données n’est qu’une surcharge. Par exemple, entre UI -> Business Facade -> Business -> Data Access -> Databaseet UI -> Database, la deuxième approche est plus rapide. Cependant, plus vous supprimez d'étapes, moins votre système devient maintenable et plus la duplication apparaît. Imaginez écrire le code nécessaire pour récupérer la liste d'amis dans le profil, la page d'accueil, la page de gestion des démons, etc.

Il convient donc ici de trouver un équilibre entre des performances plus élevées (qui bien sûr affectent directement une évolutivité plus élevée) et une meilleure facilité de maintenance .

Toutefois, ne vous limitez pas aux sujets de connexion à la base de données lorsque vous songez à créer des sites Web hautement évolutifs. Considérez ces éléments aussi:

  1. Choisir la bonne plate-forme (PHP est plus rapide en raison de sa nature scriptante, mais ASP.NET a besoin de compiler le fichier demandé à la volée pour le traiter et le servir. En outre, node.js est supposé être plus évolutif, en raison de son rappel architecture basée )
  2. Utilisation de l'architecture RESTful au lieu du modèle de service Web (SOA)
  3. Utilisation de JSON pour le transfert de données au lieu de XML (ce qui entraîne moins d'octets à transférer)
  4. Suivre les directives de performance de Yahoo
  5. Sujets liés au réseau et au matériel, tels que l'équilibrage de la charge ou l' architecture de niveau

2
Vous ne pouvez pas dire que PHP est plus rapide. Des applications ASP.NET correctement écrites peuvent souvent surperformer PHP. naspinski.net/post/AspNet-vs-php--speed-comparison.aspx
Andrew Lewis

+1 En fait, votre solution "simple" serait, Interface utilisateur -> Accès aux données -> Base de données. 2 REST est 'facile' car il est déjà intégré à la plupart des navigateurs. Pas besoin de recréer la roue API de commande-réponse. 3 Non seulement JSON est-il plus petit, mais il nécessite moins d'étapes de sérialisation-désérialisation car vous n'avez pas besoin de vérifier les entités HTML. Bon produit.
Evan Plaice

1

Il existe deux manières principales d’agrandir, de déployer et d’extraire.

La mise à l'échelle consiste à remplacer une machine par une machine plus puissante. La mise à l'échelle signifie l'ajout d'une autre machine pour effectuer le travail effectué par les machines existantes.

Tout site Web à fort trafic doit pouvoir évoluer. L'architecture logicielle à réaliser est telle qu'il est possible d'ajouter facilement plus de machines à mesure que le site est occupé.

Habituellement, cela signifie que l’application doit être divisée en niveaux afin que l’on puisse connecter et utiliser plus de serveurs à chaque niveau.

Je ferais l'option 1, avoir un service au lieu de le faire directement. Jusqu'à présent, vous ne pouvez mettre à l'échelle une application monolithique.


0

Développez votre site à l'aide d'une plate-forme technologique intégrant totalement le support du cloud.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.