240 votes

Tactiques pour l’utilisation de PHP dans un site de charge élevée

Avant de répondre à cela, je n'ai jamais développé quelque chose de assez populaire pour atteindre le haut de la charge du serveur. Traite-moi comme l' (soupir) un étranger qui vient tout juste de débarquer sur la planète, mais celui qui sait PHP et quelques techniques d'optimisation.


Je suis le développement d'un outil en PHP qui pourrait atteindre beaucoup d'utilisateurs, si il fonctionne correctement. Cependant, alors que je suis parfaitement capable de développer le programme, je suis assez désemparés quand il s'agit de faire quelque chose qui peut faire face avec un énorme trafic. Voici donc quelques questions sur elle (n'hésitez pas à son tour à cette question dans un thread de ressources).

Les bases de données

Pour le moment j'ai l'intention d'utiliser les fonctions MySQLi en PHP5. Cependant, comment dois-je configurer les bases de données en relation avec les utilisateurs et le contenu? Dois-je réellement besoin de plusieurs bases de données? Pour le moment tout est brouillé dans une base de données - même si j'ai été envisagent de propagation des données de l'utilisateur à un, réel contenu à l'autre et, enfin, de base le contenu du site (modèle de maîtres, etc.) à l'autre. Mon raisonnement derrière cela est que l'envoi des requêtes à différentes bases de données, permettra d'alléger la charge sur une base de données = 3 chargez sources. Aussi serait-ce encore être efficaces s'ils étaient tous sur le même serveur?

La mise en cache

J'ai un modèle qui est utilisé pour créer les pages et la permutation des variables. Maître modèles sont stockés dans la base de données et chaque fois qu'un modèle est appelé la copie mise en cache (document html) est appelée. Pour le moment j'ai deux types de variables dans ces modèles - static var et de la dynamique de la var. Statique vars sont généralement des choses comme les noms de page, le nom du site - des choses qui ne changent pas souvent; dynamique de vars sont des choses qui changent à chaque chargement de la page.

Ma question à ce sujet:

Dire que j'ai des commentaires sur les différents articles. Ce qui est une meilleure solution: stocker le simple modèle de commentaire et de rendre les commentaires (à partir d'une base d'appel) à chaque fois que la page est chargée ou stocker une copie en cache de la page de commentaires comme une page html - chaque fois qu'un commentaire est ajouté/modifié/supprimé la page est recached.

Enfin

Quelqu'un aurait-il des conseils ou des indications pour l'exécution d'une charge élevée de site sur PHP. Je suis sûr que c'est une pratique de la langue à utiliser Facebook et Yahoo! lui donner une grande priorité - mais existe-il des expériences que je devrais faire attention?

89voto

Gary Richardson Points 7371

Pas de deux sites se ressemblent. Vous avez vraiment besoin pour obtenir un outil comme jmeter de référence et de voir où votre problème de points. Vous pouvez passer beaucoup de temps à deviner et à améliorer, mais vous ne verrez pas de vrais résultats jusqu'à ce que vous mesurer et de comparer vos modifications.

Par exemple, pendant de nombreuses années, le MySQL query cache était la solution à tous nos problèmes de performance. Si votre site est lent, MySQL experts a suggéré de transformer le cache de requêtes. Il s'avère que si vous avez une forte charge d'écriture, le cache est en fait rédhibitoire. Si vous l'avez allumé sans le tester, vous ne le savez.

Et n'oubliez pas que vous n'êtes jamais fait de mise à l'échelle. Un site qui traite de 10req/s aurez besoin de modifications pour prendre en charge 1000req/s. Et si vous êtes lucking assez pour avoir besoin d'un soutien de 10 000 req/s, votre architecture sera probablement un aspect complètement différent.

Les bases de données

  • Ne pas utiliser MySQLi -- AOP est "moderne" OO base de données de la couche d'accès. La caractéristique la plus importante de l'usage est réservé dans vos requêtes. Il est assez intelligent pour utiliser côté serveur prépare et d'autres optimisations pour vous.
  • Vous ne voulez probablement pas à casser votre base de données jusqu'à ce point. Si vous constatez que l'un de la base de données n'est pas le découpage, il y a plusieurs techniques à l'échelle, en fonction de votre application. La réplication à d'autres serveurs fonctionne généralement bien, si vous avez plus de lectures que de l'écrit. La fragmentation est une technique permettant de séparer vos données sur plusieurs machines.

La mise en cache

  • Vous ne voulez probablement pas à le cache dans votre base de données. La base de données est généralement le goulot d'étranglement, afin d'ajouter plus d'IO, c'est généralement une mauvaise chose. Il y a plusieurs PHP caches là que d'accomplir des choses analogues à l' APC et Zend.
  • Mesurer votre système avec la mise en cache sur et en dehors. Je parie que votre cache est plus lourd que de servir les pages de droite.
  • Si il faut du temps pour construire vos commentaires et l'article de données à partir de la db, intégrer memcache dans votre système. Vous pouvez mettre en cache les résultats de la requête et de les stocker dans une instance memcached. Il est important de se rappeler que la récupération des données à partir de memcache doit être plus rapide que l'assemblage de la base de données pour voir aucun avantage.
  • Si vos articles ne sont pas dynamiques, ou vous avez de simples changements de dynamique après il est généré, envisager d'écrire du html ou php pour le disque. Vous pourriez avoir une index.php page sur le disque pour l'article, si il y est, il la transmet au client. Si ce n'est pas le cas, il génère de l'article, écrit sur le disque et l'envoie au client. Suppression de fichiers à partir du disque serait la cause de pages pour être ré-écrite. Si un commentaire est ajouté un article, supprimer la copie mise en cache, ce serait régénéré.

61voto

thesmart Points 1512

Je suis un développeur principal sur un site avec plus de 15M utilisateurs. Nous avons eu très peu de mise à l'échelle des problèmes parce que nous avons prévu pour le DÉBUT et l'échelle de façon réfléchie. Voici certaines des stratégies que je peux suggérer à partir de mon expérience.

SCHÉMA Tout d'abord, pour éliminer vos schémas. Cela signifie que plutôt que d'avoir plusieurs tables relationnelles, vous devriez plutôt opter pour une grande table. En général, les jointures sont un gaspillage de précieuses DB ressources en raison de la réalisation de plusieurs prépare et classement des brûlures d'e/S disque. Éviter quand vous le pouvez.

Le compromis est ici que vous serez stockage/tirant de données redondantes, mais c'est acceptable parce que les données et intra-cage de la bande passante est très bon marché (plus de disques), alors que de multiples préparer les I/O sont des ordres de grandeur plus cher (plus de serveurs).

L'INDEXATION Assurez-vous que vos requêtes utilisent au moins un indice. Attention cependant, les index va vous coûter cher si vous rédiger ou mettre à jour fréquemment. Il y a quelques expérimentale astuces pour éviter cela.

Vous pouvez essayer d'ajouter des colonnes supplémentaires qui ne sont pas indexés qui sont parallèles à votre colonnes indexées. Ensuite, vous pouvez avoir une connexion hors processus qui écrit les colonnes non indexées sur les colonnes indexées par lots. De cette façon, vous pouvez mieux contrôler lorsque mySQL aurez besoin de recalculer l'indice.

Éviter calculée requêtes comme une peste. Si vous devez calculer une requête, essayez de le faire une seule fois lors de l'écriture de temps.

La mise en CACHE Je recommande fortement de Memcached. Il a été prouvé par les plus grands acteurs sur la pile PHP (Facebook) et est très flexible. Il existe deux méthodes pour faire cela, on est la mise en cache dans votre base de données de la couche, l'autre est mise en cache dans votre couche de logique métier.

La DB de la couche exigerait la mise en cache le résultat de requêtes (extrait de la DB. Vous pouvez hachage de la requête SQL à l'aide de md5() et de l'utiliser comme une recherche de la clé avant d'aller à la base de données. L'avantage, c'est qu'il est assez facile à mettre en œuvre. Le revers de la médaille (selon mise en œuvre), c'est que vous perdre de la souplesse parce que vous êtes de les traiter tous de la mise en cache même à l'égard de l'expiration du cache.

Dans la boutique où je travaille, nous utilisons la couche de mise en cache, ce qui signifie que chaque classe concrète dans notre système de contrôle de sa propre mise en cache de schéma et de mettre en cache des délais d'attente. Cela a très bien fonctionné pour nous, mais sachez que les éléments extraits de DB ne peut pas être le même que les éléments de la mémoire cache, de sorte que vous aurez à mettre à jour le cache et DB ensemble.

LES DONNÉES DE FRAGMENTATION La réplication ne mène pas loin. Plus tôt que vous ne le pensez, votre écrit va devenir un goulot d'étranglement. Pour compenser, assurez-vous d'en charge les données de la fragmentation tôt possible. Vous aurez probablement envie de tirer vous-même plus tard si vous n'avez pas.

Il est assez simple à mettre en œuvre. Fondamentalement, vous voulez séparer la clé de l'autorité de la mémoire de données. Global DB pour stocker une correspondance entre les clés primaires et cluster id. Vous interrogez ce mapping pour obtenir un cluster, puis requête du cluster pour obtenir les données. Vous pouvez mettre en cache l'enfer hors de cette opération de recherche, ce qui va rendre négligeable l'opération.

L'inconvénient est qu'il peut être difficile de rassembler des données à partir de plusieurs fragments. Mais, vous pouvez transformer votre chemin autour de cela.

LE TRAITEMENT HORS LIGNE Ne faites pas l'utilisateur d'attendre pour votre backend si ils n'ont pas à. Construire une file d'attente de travail et de déplacer tout traitement que vous pouvez en mode hors connexion, faire distincte de la demande de l'utilisateur.

41voto

Ryan Doherty Points 16448

J'ai travaillé sur quelques sites qui ont des millions/hits/mois soutenu par PHP et MySQL. Voici quelques règles de base:

  1. Cache, cache, cache. La mise en cache est le moyen le plus simple et le plus efficace des moyens de réduire la charge sur votre serveur web et base de données. Cache le contenu de la page, de requêtes, de calcul coûteux, tout ce qui est I/O bound. Memcache est mort simple et efficace.
  2. L'utilisation de plusieurs serveurs une fois que vous êtes au maximum. Vous pouvez avoir plusieurs serveurs web et plusieurs serveurs de base de données (réplication).
  3. Réduire l'ensemble de la # demande à votre serveur internet. Cela implique la mise en cache JS, CSS et les images en utilisant expire en-têtes. Vous pouvez également déplacer votre contenu statique à un CDN, ce qui permettra d'accélérer votre expérience utilisateur.
  4. Mesure et de référence. Exécuter Nagios sur vos machines de production et de test de charge sur votre dev/serveur de qa. Vous avez besoin de savoir quand votre serveur va attraper le feu de sorte que vous pouvez l'empêcher.

Je vous recommande la lecture de Construction Évolutive des Sites web, il a été écrit par l'un des Flickr ingénieurs et est une grande référence.

Check out my blog post sur l'évolutivité de trop, il a un grand nombre de liens vers des présentations sur la mise à l'échelle avec de multiples langages et plates-formes: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/

39voto

DavidM Points 8591

Re: AOP / MySQLi / MySQLND

@gary

Vous ne pouvez pas simplement dire "ne pas utiliser MySQLi" car ils ont des objectifs différents. PDO est presque comme une couche d'abstraction (bien qu'il n'est pas fait) et est conçu pour le rendre facile à utiliser plusieurs produits de base de données alors que MySQLi est spécifique à MySQL conections. Il est faux de dire que PDO est la moderne de la couche d'accès dans le contexte de la comparer à MySQLi parce que votre déclaration implique que la progression a été mysql -> mysqli -> PDO qui n'est pas le cas.

Le choix entre MySQLi et PDO est simple - si vous avez besoin d'un support pour plusieurs produits de base de données, alors vous utiliser PDO. Si vous utilisez MySQL puis vous pouvez choisir entre PDO et MySQLi.

Alors pourquoi voudriez-vous choisir MySQLi plus de PDO? Voir ci-dessous...

@ross

Vous avez raison à propos de MySQLnd qui est le plus récent MySQL de base de niveau de langue, bibliothèque, mais il n'est pas un remplacement pour MySQLi. MySQLi (AOP) reste la façon dont vous interagissez avec MySQL par le biais de votre code PHP. Deux libmysql comme le C client derrière le code PHP. Le problème est que libmysql est à l'extérieur de la base moteur PHP, et c'est là que mysqlnd vient de dire qu'il est un Pilote Natif qui rend l'utilisation de la base de PHP internals pour maximiser l'efficacité, notamment lorsque l'utilisation de la mémoire.

MySQLnd est développé par MySQL eux-mêmes et a récemment débarqué sur le PHP 5.3 branche qui est en RC tests, prêt pour une sortie plus tard cette année. Vous serez alors en mesure d'utiliser MySQLnd avec MySQLi...mais pas avec PDO. Cela donnera à MySQLi un gain de performances dans de nombreux domaines (pas tous) et permettra de faire le meilleur choix pour MySQL interaction si vous n'avez pas besoin de l'abstraction comme les capacités de l'AOP.

Cela dit, MySQLnd est maintenant disponible dans PHP 5.3 pour les AOP et si vous pouvez obtenir les avantages de l'amélioration des performances de ND en PDO, cependant, PDO est encore un générique couche de base de données et seront donc peu de chances d'être en mesure de profiter d'améliorations dans ND que MySQLi peut.

Certaines des références utiles peuvent être trouvés ici bien qu'ils sont à partir de 2006. Vous devez également être conscient des choses comme cette option.

Il ya beaucoup de considérations qui doivent être prises en compte au moment de décider entre MySQLi et PDO. Une réalité qu'il ne va pas à la matière jusqu'à ce que vous obtenez à rediculously haute numéros de demande et dans ce cas, il est plus judicieux d'utiliser une extension qui a été spécialement conçu pour MySQL plutôt que des résumés des choses et qui arrive à fournir un pilote MySQL.

Ce n'est pas une simple question de qui est le meilleur parce que chacun a des avantages et des inconvénients. Vous avez besoin de lire les liens que j'ai fournis et de venir avec votre propre décision, puis de le tester et de trouver. J'ai utilisé PDO dans les projets passés et c'est une bonne extension, mais mon choix pour la performance pure serait MySQLi avec la nouvelle MySQLND option compilé (lorsque PHP 5.3 est libéré).

23voto

Paul Kroll Points 571

Général

  • Ne pas essayer de l'optimiser avant de vous commencer à voir le monde réel de la charge. Vous pouvez le deviner, mais si vous ne le faites pas, vous avez perdu votre temps.
  • Utiliser jmeter, xdebug ou un autre outil de référence du site.
  • Si la charge commence à être un problème, soit de l'objet ou de la mise en cache des données sera probablement impliqués, de sorte que généralement lire sur les options de mise en cache (memcache, MySQL options de mise en cache)

Code

  • Le profil de votre code, de sorte que vous savez où le goulot d'étranglement est, et si c'est dans le code ou dans la base de données

Les bases de données

  • Utiliser MYSQLi si la transférabilité à d'autres bases de données n'est pas vital, PDO autrement
  • Si les valeurs de référence de révéler la base de données est le problème, vérifiez les requêtes avant de commencer la mise en cache. Utilisez EXPLIQUER pour voir où vos requêtes sont en train de ralentir.
  • Après les requêtes sont optimisées et la base de données est mis en cache, vous pouvez utiliser plusieurs bases de données. Soit de la réplication sur plusieurs serveurs ou de fragmentation (répartition des données sur plusieurs bases de données/serveurs) peut être approprié, selon les données, les requêtes, et le genre de lecture/écriture de comportement.

La mise en cache

  • Beaucoup de l'écriture qui a été fait sur la mise en cache de code, les objets et les données. Rechercher les articles sur APC, Zend Optimizer, memcached, QuickCache, JPCache. Faire partie de cette avant de vous en avez vraiment besoin, et vous serez moins inquiet de départ unoptimized.
  • APC et Zend Optimizer sont des caches d'opcode, ils accélèrent le code PHP en évitant de ré et de la recompilation du code. Généralement simples à installer, la peine de le faire au début.
  • Memcached est un générique de cache, que vous pouvez utiliser pour mettre en cache les requêtes, les fonctions PHP ou des objets, ou des pages entières. Le Code doit être écrit spécifiquement pour l'utiliser, ce qui peut être un processus compliqué si il n'y a pas des points centraux de gérer la création, la mise à jour et suppression d'objets mis en cache.
  • QuickCache et JPCache, sont des fichiers caches, sinon semblable à Memcached. Le concept de base est simple, mais exige également le code et c'est plus facile avec des points centraux de la création, de mise à jour et de suppression.

Divers

  • Envisager d'autres serveurs web de charge élevée. Des serveurs comme lighthttp et nginx peut gérer de grandes quantités de trafic en beaucoup moins de mémoire que Apache, si vous pouvez sacrifier Apache de la puissance et de la souplesse (ou si vous n'avez pas besoin de ces choses, qui, souvent, vous n'avez pas).
  • Rappelez-vous que le matériel est étonnamment bon marché ces jours-ci, alors assurez-vous de coût de l'effort pour optimiser un gros bloc de code par rapport à "nous allons acheter un monstre serveur."
  • Envisager d'ajouter le "MySQL" et "l'échelle" des tags à cette question

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X