Forum Programmation.php Architecture tolérance de panne en LAMP : des conseils ?

Posté par . Licence CC by-sa
Tags : aucun
2
29
juin
2015

Bonjour à tous.

J'ai une application PHP+MySQL qui est actuellement déployée de la manière suivante (je simplifie) :
- deux serveurs Apache avec un loadbalancer en amont (ils executent la même application)
- le code source de l'application et les ressources statiques (css, js) sont sur un partage NFS
- les sessions PHP sont sur NFS
- les "upload" que font les utilisateurs sont aussi sur NFS
- Un serveur de BD MySQL (la BD est en local)
En gros, l'application est un CMS (pensez à Joomla ou Wordpress).

Ces 3 serveurs + le NFS sont interconnecté sur un réseau. Le réseau est considéré comme "fiable et hautement disponible".

Par contre, on me demande de réfléchir à une architecture qui soit plus robuste en cas de défaillance d'Apache, du NFS ou de MySQL :
- pour les frontaux apache : j'ai un loadbalancer, donc en cas de panne d'un des Apache, l'autre prend le relai
- les sessions étant sur le NFS, les utilisateurs ne perdent pas la session en cas de crash d'un serveur Apache, mais le NFS a un problème de "Lock" avec les sessions PHP
- En cas de défaillance de NFS, tout est perdu (l'application est KO)
- En cas de défaillance de MySQL, une grande partie de l'appli est perdue (on considère que toute les pages n'ont pas besoin de la bd).
- Notre NFS (une baie Netapp) est utilisé par d'autres projets, et commence a donner des signes de fatigue (latence importante + indisponibilité de temps à autre).

Pour augmenter un peu la tolérance à la panne de mon application, je mets en place les solutions suivantes :
- le code de l'application + ressources statiques seront en local sur Apache (avec rSync entre les serveurs)
- les sessions seront stockées dans deux bases REDIS maitre/escalve grace au connecteur natif PHP
- le "simple" MySQL devient un "MySQL CLUSTER NDB" (deux serveurs maitres répliqués entre-eux)
Le problème qu'il me reste à résoudre est "les uploads des utilisateurs" qui se faisaient sur NFS. Si le NFS est KO, le utilisateurs ne peuvent plus faire d'upload.
Je souhaite minimiser aussi l'impact sur l'application PHP pour ne pas avoir à tout redévelopper.

Avez-vous déja mis en place une architecture à haute tolérance de panne sur un produit LAMP pas vraiment prévu pour cela à la base ? D'une manière générale, par quoi pourrais-je remplacer NFS dans mon infrastructure ? Avez-vous des infrastructures "types" qui permettent de faire de la haute-dispo LAMP ?

J'ai étudié les solutions suivantes :
- upload en local (sur le Apache sur lequel l'utilisateur est connecté) puis réplication Rsync entre les serveurs : pas jouable si on augmente le nombre de serveur Apache et le nombre d'upload (le systeme va passer son temps à synchroniser), et de plus cela introduit un délai entre l'upload et la prise en compte par les frontaux.
- upload non pas sur le filesystem mais dans la BD Redis ou MySQL : je n'aime pas trop stocker du binaire dans une BD. J'aurais la possibilité de mettre MongoDB (en répartition sur plusieurs serveurs), mais j'ai peur que les perfs ne soient pas au rendez-vous.
- systeme de fichier réparti (GPFS ou autre) : semble complexe a mettre en oeuvre, surtout en mode "faut que ca coute pas cher"

Merci !

Quand tout sera en place, je ferais un retour par ici.

Jerome.

  • # Une bonne multiprise et deux baladeuses

    Posté par . Évalué à 1.

    OK je sors ===>[]

  • # https://en.wikipedia.org/wiki/Comparison_of_distributed_file_systems

    Posté par . Évalué à 1.

    Pour de la haute dispo de fichiers, un systeme de fichier réparti ne me paraît pas trop mal
    Il semblerait que Ceph
    ou GlusterFS ne soient pas si complexe que ça (et ils sont libres et gratuits).
    Note : A vu de nez, je privilégierais GlusterFS, car il peut apparement être monté en NFS, ce qui pourrait te permettre de ne pas trop modifier l'archi existante et parcqu'il est apparemment plus performant (d'après de vieux benchmarks)

  • # Fiabiliser les couches basses.

    Posté par . Évalué à 2.

    Tu es en train de complexifier dangereusement l'application, ce qui va rendre la maintenance difficile et coûteuse.
    A mon avis il vaut mieux fiabiliser les couches basses (réseau, stockage, ordinateur) et laisser l'application telle qu'elle est.

    Pour le stockage: il te faut un cluster haute-disponibilité.
    Si tu n'as pas de budget tu peux mettre en place un cluster CEPH, mais tu vas y passer vraiment beaucoup de temps, et donc au final tu ne sera pas gagnant. Ca serait mieux d'acheter une baie Netapp FAS2500 avec deux contrôleurs.

    Pour l'ordinateur, le plus simple c'est de faire tourner ton application dans une machine virtuelle s'exécutant sur un cluster haute-disponibilité. Si tu as trois machines identiques, tu peux en créer un très facilement et gratuitement en une heure avec Xenserver 6.5. Tu ne payes que si tu veux un contrat de support auprès de Citrix.

    Liens:
    http://www.netapp.com/us/products/storage-systems/fas2500/fas2500-tech-specs.aspx
    https://2013.jres.org/archives/48/paper48_article.pdf
    http://xenserver.org

    • [^] # Re: Fiabiliser les couches basses.

      Posté par . Évalué à 1.

      Merci pour ces informations.

      Les infra Redis et MySQL Cluster NDB sont déja utilisé par ailleurs chez nous, donc cela ne pose pas vraiment de problème de mise en place et de maintenance (c'est deja industrialisé, supervisé etc.). Ce sont déja des VM dans un cluster Xen.

      Pour remplacer le NFS, je pars en effet plutot sur du stockage distribué (glusterfs ou ceph). Mais c'est certain qu'avoir une baie Netapp dédiée à cela serait plus simple à mettre en oeuvre. Ca va surtout dépendre du prix d'achat + support.

  • # Mon avis

    Posté par . Évalué à 1.

    Afin d'éviter le NFS (qui comme tu l'indiques va probablement poser plus de problèmes qu'il n'en résoud) tu as deux choix:

    • stocker les sessions dans mysql (ou dans une autre DB NoSQL, mais MySQL peut très bien faire l'affaire), les sessions c'est du PHP serializé (donc du texte), normallement c'est "petit" et ça ne pose pas de problèmes, les perfs sont au rendez-vous.

    • garder les sessions locales et mettre le load balancer en mode "sticky" (il y a différentes possibilités), le but étant qu'un même client va toujours finir sur la même instance et donc retrouver sa session

    Précédement j'utilisais la solution 1, maintenant je tourne sur la 2 (cela dit je n'ai pas grand chose à reprocher à la première approche, mais vu que le mode "sticky" fonctionne bien, il n'y a même plus besoin de "patcher" le système de sessions).

    • [^] # Re: Mon avis

      Posté par . Évalué à 1.

      Pour les fichiers partagés entre les instances j'utiliserais effectivement MongoDB. Dans mon cas j'ai surtout utilisé Amazon S3 dont j'apprécies toutes les fonctionnalités complémentaires et le service coûte très peu cher si le stockage se calcule en Go plutôt qu'en To. Si tu n'est pas hébergé chez AWS, la latence additionnelle peut être compensé par un cache local à l'application.
      Afin de se simplifier la vie avec le cache, dans la plupart de scénarios, le fichier était stocké avec comme nom/clé son md5 ce qui simplifie grandement l'implémentation du cache local. Les métas data du fichier étant, si besoin, dans MySQL. Dans la plupart des cas il est simple de déterminer le type de fichier en lisant les 1ers octets aussi (si on a pas besoin de récupérer le nom original par exemple mais juste de renvoyer les bon headers).

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.