Jofrey Posté 26 Novembre 2009 Posté 26 Novembre 2009 (modifié) Bonjour, Je suis webdesigner/développer et j'ai une demande particulière d'un client concernant l'hébergement de son site internet. Voilà en gros, je ne rentre pas trop dans les détails du site en lui même mais la problématique ce situe dans l'infrastructure à mettre en place : Le site doit gérer en moyenne entre 200 et 500 connexions simultanées, jusque là rien de problématique sauf qu'une fois par mois lors d'un événement, il devra avoir besoin de supporter au minimum 7500 connexions simultanées et jusqu' à 15000 connexions simultanées. Et quand je dis 15000 c'est à un instant t pendant environ 1 heure. C'est à dire pour être plus précis, à 20h le 10 mars 2010, on doit pouvoir gérer ces 15000 visiteurs et ce jusque 21h/22h. La dessus vient ce greffer les requêtes des visiteurs à une base données pendant cette périodes, celui-ci seront je pense réparti par ordre décroissante sur la durée de l'événement. Ma question est de savoir qu'elles sont les moyens à mettre en œuvre pour obtenir une disponibilité en ressources pour gérer cette afflux ? De manière théorique et pratique. En vous remerciant par avance de pour votre aide, Cordialement, Jofrey. Modifié 26 Novembre 2009 par Jofrey
Kioob Posté 26 Novembre 2009 Posté 26 Novembre 2009 Bonsoir, pour commencer il faudrait être sûr de ce dont on parle : quand tu indiques 15'000 connexions simultanées, c'est : * le nombre de sessions PHP actives à un instant T* le nombre de visiteurs ayant accéder à une page durant les 120 dernières secondes* le nombre de connexions keepalive ouvertes sur le serveur http* le nombre de téléchargements simultanés* le nombre de téléchargements simultanés de pages dynamiques Déjà en fonction de ces 5 cas, la solution changera radicalement. Pour la première par exemple, il n'y a pas forcément besoin de faire quoi que ce soit. Pour les deux suivantes, il faut surtout faire attention au nombre de slots autorisés par Apache (si toutefois tu utilises Apache), en particulier si tu utilises autre chose que le mpm_event d'Apache et que le keepalive est actif. Enfin pour les deux derniers cas, c'est probablement à évaluer au cas par cas, une solution peut consister à utiliser Varnish en frontal afin de maintenir un cache statique, ne serait ce que de quelques secondes. Ca c'est uniquement pour dégrossir. Après faut voir en détail le code PHP, les requêtes SQL utilisées ainsi que le modèle de données. A haut régime le moindre verrou peut tout faire tomber. Sans oublier d'autres aspects qui peuvent parfois être bloquant : le firewall, la bande passante, ou même le système de logs. Il faudra bien tester tout ça avant la mise en prod afin d'éviter de mauvaises surprises.
Jofrey Posté 26 Novembre 2009 Auteur Posté 26 Novembre 2009 (modifié) Bonjour, Je vais être un peu plus clair parce que je pense que ça doit recouvrir un peu de tout ça La demande du client est : J'organise un concours ( sous forme de questionnaire ) où doit participer simultanément au minimum 7500 personnes et au maxi 15000. Ces personnes devront être connecté sur leurs comptes (donc session PHP) à 20h pour participer. Sachant que pour des raisons de droits, ils doivent avoir accès à la page du questionnaire exactement au même instant… En suite ils doivent répondre le plus rapidement possible. Valider (donc enregistrement dans la base de données). Voilà, j'espère que c'est plus claire comme ça. Merci ! Modifié 26 Novembre 2009 par Jofrey
Kioob Posté 26 Novembre 2009 Posté 26 Novembre 2009 Yep, c'est déjà plus précis oui. Donc pour récapituler, on est sûr d'avoir au moins le cas n°1 : jusqu'à 15'000 sessions PHP ouvertes. Déjà va peut être falloir faire attention à la méthode de stockage de celles-ci (les placer en mémoire de préférence et/ou avec une répartition sur deux niveaux). Coté keepalive, si les 15'000 se pointent plus ou moins dans la même minute, le cas n°3 risque de vite se présenter. Dans ce cas pour moi il faut prévoir un serveur http gérant correctement le keepalive (apache-mpm-event, nginx, varnish, lighty, etc) ou bien carrément le désactiver (à conditions que les fichiers statiques soient sur un autre serveur...). Le problème de varnish pour le coup va être les sessions : difficile de mettre en cache un contenu spécifique à chaque utilisateur. Reste que théoriquement si les 15'000 se pointent strictement en même temps, PHP va avoir bien du mal à gérer cela. A raison de 4Mo minimum par instance de PHP, ça va être tendu... et j'espère que ce n'est pas un CMS bouffant 30Mo par page qui fait tourner ça. Heureusement en pratique il y a peu de chances pour que les visiteurs cliquent au même instant sur le bouton. Il s'agit d'approximations, mais si par exemple on accepte un délai de 10 secondes pour l'affichage de la page, et que le traitement PHP ne dure que 50ms, et que derrière on accepte 50 processus simultanés, on est déjà à 10'000 exécutions (sous 10 secondes). Maintenant tout va dépendre du délai de réponse acceptable, et du temps de traitement réel coté PHP. On en revient un peu au même : va falloir tester avec un simulateur de charge.
jcaron Posté 26 Novembre 2009 Posté 26 Novembre 2009 +1 avec Kioob, on n'est plus au temps du Minitel, les connexions "simultanées" en http c'est un élément à géométrie variable (rappel: un navigateur est connecté au serveur le temps de charger la page et ses éléments, éventuellement quelques secondes après au cas où, puis il se déconnecte, il ne reste pas connecté tout le temps que la page est affichée). En général, on compte plutôt en nombre de requêtes par seconde, mais couplé avec le temps d'exécution d'une requête (CPU + latence accès bdd ou ressources externes) et les mécanismes de Keep-Alive, ça a une influence sur le nombre de connexions TCP (et de processus ou threads) simultanés. Une "session php" ça ne consomme rien. Pour moi il y a trois parties: - les connexions avant 20h - le "dévoilement du questionnaire" - les connexions après pour soumettre les réponses Le dévoilement du questionnaire peut être fait de plusieurs façons: - quand le gars se connecte avant 20h on lui envoie le questionnaire quand même, mais il est "caché", et ne sera dévoilé qu'à l'heure dite sans nouvelle connexion au serveur. Evidemment il faut prendre un minimum de mesures pour que le gars ne puisse pas juste regarder le source une heure avant pour le récupérer, et il faut assurer un minimum de synchro (i.e. ne pas tenir compte bêtement de l'heure du PC) mais quoi qu'il arrive, si on veut éviter une connexion à 20h, il faut fournir tous les éléments à l'avance, et c'est donc forcément déchiffrable - on force un reload à l'heure dite. Ca veut dire 15 000 requêtes en quelques secondes. - on utiliser un système de "push" (en fait du long polling). Ca veut dire 15 000 connexions simultanées (là c'est effectivement le cas, on garde volontairement la connexion établie), et 15 000 réponses envoyées d'un coup à tout le monde - on combine la première option et l'une des deux autres pour envoyer toutes les données à l'avance, sauf une clef de déchiffrement, et on envoie juste la clef à l'heure dite. Pour le push/long polling, voir des solutions comme APE, ou faire un développement maison (avec libevent il doit être possible de développer ça en quelques centaines de lignes de C, peut-être même moins de 100). Note que quoi qu'il arrive "exactement au même instant" reste approximatif, il y aura forcément un écart de quelques millisecondes à plusieurs secondes. Pour les parties avant/après, c'est une question de prévoir à quel rythme ces connexions vont se faire. Au pire c'est 15000/seconde, au mieux ça s'étale sur des minutes donc on peut descendre à quelques dizaines de requêtes/seconde. Ne pas oublier malgré tout de compter les reloads que plein de gens vont forcément faire (ce qui entraîne des requêtes pour tous les autres fichiers inclus), et dans le cas de la soumission, les problèmes genre soumission incomplète etc qui vont forcément entraîner plusieurs soumissions. Choses à faire ou à vérifier: - essayer de rendre un maximum de contenu totalement statique - alléger autant que possible toutes les pages "sur le chemin" - séparer le contenu statique du contenu dynamique (mettre le contenu statique sur un serveur dédié super light, genre Apache sans aucun module ou presque, ou lighttpd) - supprimer les keep-alives sur le contenu dynamique - la config d'Apache en termes de nombre de clients, processus, threads, etc. - attention à faire en sorte que la machine ne swappe pas: les processus php sont très gourmands en RAM, donc si tu laisses Apache en forker trop, ta machine va te faire une mort subite - la config mysql en termes de nombres de clients etc. - la config système en termes de nombre de processus, fichiers ouverts, connexions, etc. - la config de firewalls (externes ou internes) qui limiteraient le nombre de nouvelles connexions par seconde (pensant que c'est une attaque DDOS par exemple) Si tout ça ne tient pas sur une seule machine (ce qui est possible), tu peux avoir intérêt à utiliser des solutions de serveurs virtuels "à la demande" (voir chez Gandi ou chez Amazon par exemple), que tu peux louer pour juste quelques heures et qui utilisent des "images" du serveur pré-construites. Et évidemment, tester tout ça bien à l'avance, surtout la montée en charge. On a toujours des surprises sur des paramètres auxquels on n'aurait jamais pensé... Jacques.
Jofrey Posté 26 Novembre 2009 Auteur Posté 26 Novembre 2009 Super merci à vous deux pour vos réponses, c'est déjà un peu plus clair ! Bonne soirée !
Sarc Posté 26 Novembre 2009 Posté 26 Novembre 2009 Et évidemment, tester tout ça bien à l'avance, surtout la montée en charge. On a toujours des surprises sur des paramètres auxquels on n'aurait jamais pensé... [Mode Question bête] Il y a des moyens simples de tester la qualité de réponse du serveur avec 10, 100, 1000 personnes sur le serveur, sans se faire engueuler par son hébergeur et sans devoir demander à X de ses copains d'aller s'y promener ?
Kioob Posté 26 Novembre 2009 Posté 26 Novembre 2009 sarc : sans demander aux copains oui, il y a ab (= Apache Benchmark) et siege par exemple deux outils permettant de simuler plus ou moins bien des connexions d'internautes. Par contre pour le "sans se faire engueuler par l'hébergeur", je ne tenterais certainement pas ça sur un mutualisé non.
jcaron Posté 26 Novembre 2009 Posté 26 Novembre 2009 Tu m'enlèves les mots de la bouche :-) C'est sûr, pas sur un mutualisé, mais de toutes façons je suppose (j'espère!) que le projet final n'est pas prévu pour tourner sur un mutualisé. ab c'est très bien, mais il faut bien voir une chose: si tu ne le lances que depuis une seule autre machine, tu es limité par les performances de cette machine-là, ce qui ne permet pas forcément de monter jusqu'au niveau de requêtes voulu, donc il faudra probablement "attaquer" à partir de plusieurs machines. Et ça ne prend pas forcément en compte des paramètres tels que la latence de certains utilisateurs. C'est moins vrai de nos jours maintenant que le dialup a beaucoup régressé, mais il doit encore y en avoir. Après suivant les cibles il y a les gens à l'autre bout de la planète ou ceux sur des connexions 3G etc, qui ont une latence plus élevée que celle observée depuis un autre serveur. Ca a l'air con comme ça, mais si tu as 100 ms de latence A/R sur une connexion, ça peut très nettement augmenter le temps que la connexion TCP va rester en place, et donc éventuellement qu'un processus php va rester "occupé" et squatter de la RAM pour rien (ça dépend de la façon dont php est utilisé, en module, en cgi, en fastcgi...). Il doit y avoir des services commerciaux qui permettent de faire ça à grande échelle aussi. Tiens, au passage, quelques paramètres système qu'il est utile de vérifier/modifier/augmenter carrément beaucoup quand on veut monter sérieusement en charge sur une machine FreeBSD: kern.maxfiles kern.maxfilesperproc kern.threads.max_threads_per_proc kern.ipc.somaxconn kern.ipc.maxsockets net.inet.ip.portrange.first net.inet.tcp.maxtcptw net.inet.tcp.nolocaltimewait net.inet.icmp.icmplim vm.pmap.pv_entry_max Je ne sais pas s'ils ont tous des équivalents sous Linux. Il y a certainement des paramètres qui n'ont pas besoin d'être modifiés de la sorte sous Linux, et il doit y en avoir d'autres à modifier en plus à mon avis, et ça doit évidemment varier d'une version/distribution à une autre. Certains paramètres sont aussi liés à ton architecture exacte (par exemple net.inet.ip.portrange.first et net.inet.tcp.nolocaltimewait sont utiles dans le cas où tu utilises un reverse proxy ou load balancer genre pound sur la même machine). Evidemment, il faut penser à instrumenter ta (tes) machine(s) avant de faire tes tests, histoire de pouvoir suivre au minimum la consommation de CPU et de RAM, et suivant les cas les accès disques et quelques autres paramètres genre nombre de processus, de threads, de fichiers ouverts, de connexions établies, etc. Jacques.
Jofrey Posté 26 Novembre 2009 Auteur Posté 26 Novembre 2009 (modifié) Bonsoir, Nan le projet final n'est pas prévu sur un mutualisé … J'avais penser à un ou plusieurs dédiés en fonction des réponses apportées. Mais au vu des réponses, je pense que je vais faire appel à quelqu'un pour m'aider à monter ce projet si celui-ci ce fait. En tout cas merci de partager votre expérience. Modifié 26 Novembre 2009 par olitax
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant