201211 drupagora hostingdrupal

24
Les bonnes pratiques de l’hébergement d’une application DRUPAL

Upload: oxalide

Post on 14-Dec-2014

586 views

Category:

Documents


0 download

DESCRIPTION

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

TRANSCRIPT

Page 1: 201211 drupagora hostingdrupal

Les bonnes pratiques

de l’hébergement d’une application

DRUPAL

Page 2: 201211 drupagora hostingdrupal

Sébastien Lucas@PoMM3Responsable avant-vente Designer d’infra

Nicolas Silberman@nsilbermanDirecteur TechniqueMediapart

Welcome

Page 3: 201211 drupagora hostingdrupal

Oxalide & Drupal

Page 4: 201211 drupagora hostingdrupal

Le Projet Médiapart

Présentation métier• Le projet Mediapart• Volumétrie• Taille de la Team

Médiapart & Drupal• Historique• Version : Drupal 6 non Pressflow

Page 5: 201211 drupagora hostingdrupal

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.

Page 6: 201211 drupagora hostingdrupal

Critères pour 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

Page 7: 201211 drupagora hostingdrupal

3 silosPublic Rédaction Pré-production

FORTE ChargeFORTE VariationFORTE Disponibilité

FAIBLE ChargeFAIBLE VariationFORTE Disponibilité

FAIBLE ChargeZERO VariationFAIBLE Disponibilité

Silo:-Multicouches-N-Frontal-Actif-Actif multisites-Haute disponibilité

Silo :-Mono Frontal-Isolé-Mono site

Silo autonome

Page 8: 201211 drupagora hostingdrupal

Site APA-2

ACTIF

Site BPA-3

ACTIF

LVS backend

backoffice

LVS backend

FW & Répartition de charge

Cache Front Back

preprod

Infrastructure

Page 9: 201211 drupagora hostingdrupal

Architecture logicielle

Page 10: 201211 drupagora hostingdrupal

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 Drupal

Réplication Master/Master MySQL• Vip + HeartBeat

Haute disponibilité des services Back (SolR&memcache)

• Heartbeat + réplication native master/slave (SolR) + Switch de redémarrage sur la conf

• Memcache vide

Page 11: 201211 drupagora hostingdrupal

Segmenter vos règles de cachingVarnishRègles généralesFréquence de modification faible

Mise en cache systématique avec une rétention importante pour vos médias ou pages statiques (images, js, css, 404, etc.)Supprimer les cookies « inutiles » (Analytics) & Lazy session (<7)

ApacheRègles un peu plus finesFréquence de modification épisodique

Surcharger les headers « cache-control » depuis votre conf ou .htaccess pour certaines rubriques publiques « one-to-all » de votre site (max-age=X, public|private)

Applicatif – cache-controlRègles finesModification en « temps réel »

Piloter directement depuis l’applicatif (code ou backend)

Page 12: 201211 drupagora hostingdrupal

Varnish Implémenter des stratégies « métiers » de caching

• Cache anonyme : la version du site publique sans auth

• Cache par groupe & rôle

• Cache par user

ESI pour déterminer les blocs cachables et accessibles

Page 13: 201211 drupagora hostingdrupal

sub vcl_recv{

[...]# Test d'exclusion du cache (pass = "pas de cache", lookup="accès au cache")if (req.http.Cookie){

# Test sur l'url pour déterminer si il s'agit d'une 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 l'url 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 l'ID 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}=([^;]*);*.*$", "\1\2");# C embarqué pour gérer le retour d'erreur de la fonction

Vmod_Func_memcached.get# On verifie ici si une session actuellement valide correspond ‡ l'ID 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 d'un 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)

}

Varnish Implémenter des stratégies « métiers » de caching

Page 14: 201211 drupagora hostingdrupal

sub vcl_hash{

# Si la requête est acheminée ici, alors la présence du cookie autorisé l'accè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=([^;]*);*.*$", "\1\2" ); 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=([^;]*);*.*$", "\1\2" ); hash_data(req.http.X-CACHE-ROLES); } } }

[...]}

Varnish Implémenter des stratégies « métiers » de caching

Page 15: 201211 drupagora hostingdrupal

MemcacheAffiner la stratégie de caching applicatif

• Une instance par type de données,

• Flush partiel vs flush global• 3 containers pour

Médiapart :– HTML,– Data diverse,– Session.… possible d’aller plus loin

(pages, vues, blocs, menus, filtres, etc.)

• Bien choisir la place dans l’infrastructure (local vs remote)

• Warning sur la charge réseau

FrontFront FrontFront

BackEndBackEnd BackEndBackEnd

DRUPALDRUPAL DRUPALDRUPAL

MC HTML actifMC HTML actif

MC Data actifMC Data actif

MC HTML actifMC HTML actif

MC Data actifMC Data actif

MC Data actifMC Data actif MC Session actifMC Session actifMC Session

passifMC Session

passif MC Data passifMC Data passif

MC Lock actifMC Lock actif MC Lock passifMC Lock passif

Page 16: 201211 drupagora hostingdrupal

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

Page 17: 201211 drupagora hostingdrupal

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

Page 18: 201211 drupagora hostingdrupal

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

Page 19: 201211 drupagora hostingdrupal

L’indexation

Transformer un coût variable en coût fixe

•SolR pour la recherche :– Crawl Solr– Piloté par Drupal (check module)

Page 20: 201211 drupagora hostingdrupal

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

Page 21: 201211 drupagora hostingdrupal

Monitorer l’environnement

• Varnish : Hit ratio, Remplissage des différentes instances, etc.

• Memcache : Sessions, % hits/sec, %req/sec, %evictions/sec; etc.

• MySQL : Template Percona

Page 22: 201211 drupagora hostingdrupal

Chargez !1/ Home (anonyme)2/ AuthentificationGé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/ ArticlesBoucle sur un ensemble d’url d’article extraites depuis un .csv

Affichage de la page1, page2 et des commentaires.Post d’un commentaire4/ BlogBoucle sur un ensemble d’url de blog extraite depuis un .csvPost 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

JMeter pour voir si ça tient

Page 23: 201211 drupagora hostingdrupal

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)

Page 24: 201211 drupagora hostingdrupal

Merci… des questions ?