201211 drupagora hostingdrupal

979 views
887 views

Published on

Un focus sur l'hébergement Drupal. Un cas concret "Mediapart" et des conseils sur l'amélioration de la flexibilité, maintenabilité et fiabilité.

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
979
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
20
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

201211 drupagora hostingdrupal

  1. 1. Les bonnespratiquesde l’hébergement d’une application DRUPAL
  2. 2. WelcomeSébastien Lucas Nicolas Silberman@PoMM3 @nsilbermanResponsable avant-vente Directeur TechniqueDesigner d’infra Mediapart
  3. 3. Oxalide & Drupal
  4. 4. Le Projet MédiapartPrésentation métier • Le projet Mediapart • Volumétrie • Taille de la TeamMédiapart & Drupal • Historique • Version : Drupal 6 non Pressflow
  5. 5. Les spécificités du projet Web •Trafic très variable, •Cycle de développement très court, Presse •Outil de travail de la rédaction, •Pics d’actualité non anticipables, Médiapart •Forte activité connectée, •Un e-commerçant d’un produit dématérialisé, Drupal •Riche fonctionnellement, •Travail permanent sur la performance.
  6. 6. Critèrespour bien dimensionner son infrastructure• Volumétrie & répartition du trafic• Performance & indicateurs• Pré-requis de disponibilité (SLA)• Différentes catégories de service• Provenance des visiteurs/utilisateurs : FR
  7. 7. 3 silosPublic Rédaction Pré-productionFORTE Charge FAIBLE Charge FAIBLE ChargeFORTE Variation FAIBLE Variation ZERO VariationFORTE Disponibilité FORTE Disponibilité FAIBLE DisponibilitéSilo: Silo :-Multicouches -Mono Frontal-N-Frontal Silo autonome -Isolé-Actif-Actif multisites -Mono site-Haute disponibilité
  8. 8. Infrastructure Site A PA-2 backoffice preprod ACTIF LVS backend FW & Répartition Cache Front Back de charge Site B PA-3 ACTIF LVS backend
  9. 9. Architecturelogicielle
  10. 10. Répartition de charge &HARépartition de charge de layer 3 • vers les serveurs Varnish, • vers les services internes Actif/Actif (MySQL Slaves)Répartition de charge layer 7 • Varnish vers les frontaux DrupalRéplication Master/Master MySQL • Vip + HeartBeatHaute disponibilité des services Back (SolR&memcache) • Heartbeat + réplication native master/slave (SolR) + Switch de redémarrage sur la conf • Memcache vide
  11. 11. Segmenter vos règles decachingVarnish Mise en cache systématique avec uneRègles générales rétention importante pour vos médias ouFréquence de modification faible pages statiques (images, js, css, 404, etc.) Supprimer les cookies « inutiles » (Analytics) & Lazy session (<7)Apache Surcharger les headers « cache-control »Règles un peu plus fines depuis votre conf ou .htaccess pourFréquence de modification épisodique certaines rubriques publiques « one-to-all » de votre site (max-age=X, public|private)Applicatif – cache-control Piloter directement depuis l’applicatif (codeRègles fines ou backend)Modification en « temps réel »
  12. 12. VarnishImplémenter des stratégies « métiers » decaching• Cache anonyme : la version du site publique sans auth• Cache par groupe & rôle• Cache par userESI pour déterminer les blocs cachables et accessibles
  13. 13. VarnishImplémenter des stratégies « métiers » decaching sub vcl_recv { [...] # Test dexclusion du cache (pass = "pas de cache", lookup="accès au cache") if (req.http.Cookie) { # Test sur lurl pour déterminer si il sagit dune page avec des tags ESI ou un appel ESI directement if (req.url ~ "^/esi/get" || req.url ~ "^/$" || req.url ~ "^/whatever/(a|b|c)/") { # Extraction de la stratégie de cache depuis les variables GET de lurl if (req.url ~ "^.*&cache=[^&]+$") { # assignation de la strategie de cache a un en-tete HTTP (trick varnish pour créer des variables) set req.http.X_CACHE_MODE = regsub(req.url, "^.*&cache=([^&]+).*$", "1"); } } else { return (pass) } # assignation de lID de session (extrait du cookie) à un en-tete HTTP. set req.http.X_SESS_COOKIE = "session-" + regsub(req.http.Cookie, "^.*?SESS[0-9a-zA-Z]{32}=([^;]*);*.*$", "12"); # C embarqué pour gérer le retour derreur de la fonction Vmod_Func_memcached.get # On verifie ici si une session actuellement valide correspond ‡ lID extrait du cookie. # Pour cela on utilise le vmod memcached de varnish. C{ if (Vmod_Func_memcached.get(sp, &vmod_priv_memcached, VRT_GetHdr(sp, HDR_REQ, "016X_SESS_COOKIE:")) == NULL) { /*Création dun en-tete HTTP pour positioner un flag en cas de session invalide*/ VRT_SetHdr(sp, HDR_REQ, "015X_SESS_VALID:", "Not Found", vrt_magic_string_end); } }C # exclusion du cache en cas de session invalide if (req.http.X_SESS_VALID ~ "^Not Found$") { return (pass); } } return (lookup) }
  14. 14. VarnishImplémenter des stratégies « métiers » decaching sub vcl_hash { # Si la requête est acheminée ici, alors la présence du cookie autorisé laccès au cache authentifié. if (req.http.Cookie) { hash_data("authenticated"); } # Extraction de la strategie de cache depuis le en-tête http créé précédemment if (req.http.X_CACHE_MODE) { # Stratégie de cache au niveau "user". # on hash donc la ressource sur le nom du user extrait du cookie. if (req.http.X_CACHE_MODE == "user") { if (req.http.Cookie ~ "user=") { set req.http.X-CACHE-USER = regsub( req.http.Cookie, "^.*?user=([^;]*);*.*$", "12" ); hash_data(req.http.X-CACHE-USER); } } # Stratégie de cache au niveau "rôles" # on hash donc la ressource sur le nom # du group (un groupe étant commun à plusieurs utilisateur) if (req.http.X_CACHE_MODE == "roles") { if (req.http.Cookie ~ "roles=") { set req.http.X-CACHE-ROLES = regsub( req.http.Cookie, "^.*?roles=([^;]*);*.*$", "12" ); hash_data(req.http.X-CACHE-ROLES); } } } [...] }
  15. 15. MemcacheAffiner la stratégie de caching applicatif • Une instance par type de Front Front Front Front données, • Flush partiel vs flush global DRUPAL DRUPAL DRUPAL DRUPAL • 3 containers pour Médiapart : MC HTML actif MC HTML actif – HTML, MC HTML actif MC HTML actif – Data diverse, MC Data actif MC Data actif MC Data actif MC Data actif – Session. … possible d’aller plus loin (pages, vues, blocs, menus, BackEnd BackEnd BackEnd BackEnd filtres, etc.) MC Data actif MC Data actif MC Session actif MC Session actifMC Session passifMC Session passif MC Data passif MC Data passif • Bien choisir la place dans MC Lock actif MC Lock actif MC Lock passif MC Lock passif l’infrastructure (local vs remote) • Warning sur la charge réseau
  16. 16. Optimiser Drupal• Utiliser l’API !• Attention à l’abus de modules• Dans les modules custom : penser cache.• Compilation des assets css et js minifiés (agrégation et compression)• Développer en E_STRICT• DBlog en pré-production, syslog en production• Pas de requêtes dans les thèmes
  17. 17. PHP & memcacheOptimiser l’environnement d’exécution• Apache : KeepAlive, MaxClients, MaxRequestsPerChild• Nginx + FPM : pour la faible empreinte applicative (et + FPM)• PHP Web <> PHP CLI• Memcache : memory limit  Nb de req par sec -> nombre de connexions simultanées -> lié au nombre de FD par user et espace mémoire  Nb dévictions -> ajuster le max memory  Optimisation de l’utilisation des pages des slabs
  18. 18. MySQLOptimiser l’environnement d’exécution• Utiliser innoDB pour : – rester en transactionnel – minimiser les locks, – plus de tolérance à la concurrence.• innoDB tout en RAM (innodb buffer pool size au max)• Avec les empreintes MySQL Report & Tuner, on ajuste le nombre de connexions maxi en fonction de la mémoire,• Les tables ne sont jamais très grosses• Pb sur les tables de commentaires• Sharder et/ou partitionner si nécessaire (par année ou par mois)• Répartition lecture et faire une partie des lectures dans SolR.• Pensez au NoSQL ou indexation pour vos nouveaux modules
  19. 19. L’indexationTransformer un coût variable en coûtfixe•SolR pour la recherche : – Crawl Solr – Piloté par Drupal (check module)
  20. 20. Monitorer pour optimiser• Check HTTP• XHProf : – Toutes les « n » requêtes, – Sur un max_execution_time• Xdebug/Webgrind en mode trigger pour troubleshooter avec un watchdog qui simule une visite via lib curl• Pinba (mod PHP et mod nginx => pour faire remonter le monitoring applicatif au niveau du serveur web),• Newrelic,• Plugin munin• Log Watchdog dans mongoDB pour les logs
  21. 21. Monitorerl’environnement • Varnish : Hit ratio, Remplissage des différentes instances, etc. • Memcache : Sessions, % hits/sec, %req/sec, %evictions/sec; etc. • MySQL : Template Percona
  22. 22. Chargez !JMeter pour voir si ça tient 1/ Home (anonyme) 2/ Authentification ⇒Génération dynamique du form_build_id pour les variables du POST http Utilisation d’un pré-processeur beanshell (un composant Jmeter) pour l’exécution d’un script php avecla logique Drupal pour générer des id de formulaire unique. ⇒Extraction des login/password depuis un .csv contenant l’ensembles des comptes. 3/ Articles ⇒Boucle sur un ensemble d’url d’article extraites depuis un .csv Affichage de la page1, page2 et des commentaires. ⇒Post d’un commentaire 4/ Blog ⇒Boucle sur un ensemble d’url de blog extraite depuis un .csv ⇒Post d’un billet de blog Parsing du formulaire html pour l’extraction d’un id de formulaire unique. (via l’utilisation d’un regexp sur la page html). 5/ Déconnexion
  23. 23. Piloter vos déploiements• Versionner : CVS/SVN/Git• Déployer : Capistrano• Drush : Mise à jour du schéma des bases en fonction du modèle, etc.• Piloter : Drush & Varnish – Warning bcp de choses en base => Coupler Capistrano pour activer Drush : Déploiement de fichiers + commande Drush (versioné dans Scripts shell)
  24. 24. Merci… des questions ?

×