jeremm

Jérémy MURIEL ( jeremy [at] jeremm [dot] fr )

Sep 262013
 

Ajouter les paquets :

echo 'deb http://repo.percona.com/apt wheezy main' > /etc/apt/sources.list.d/percona.list
gpg --keyserver  hkp://keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A ; gpg -a --export CD2EFD2A | apt-key add -
apt-get update
apt-get install percona-xtradb-cluster-server-5.5 xtrabackup

Ajouter la configuration au my.cnf:

# Cluster
wsrep_provider                  = /usr/lib/libgalera_smm.so
wsrep_cluster_address           = gcomm://192.168.0.211,192.168.0.212,192.168.0.213
wsrep_slave_threads             = 8
wsrep_sst_method				= xtrabackup
wsrep_sst_auth                  = debian-sys-maint:<password>
wsrep_cluster_name              = test_cluster
wsrep_node_name                 = M1
wsrep_node_address              = 192.168.0.211
binlog_format                   = ROW
default_storage_engine          = InnoDB
innodb_autoinc_lock_mode        = 2
innodb_locks_unsafe_for_binlog  = 1
transaction-isolation           = READ-COMMITTED
wsrep_causal_reads              = OFF

Pour démarrer le premier serveur du cluster la première fois, utiliser la commande :

/etc/init.d/mysql bootstrap-pxc

Il faut au minimum 3 serveurs pour éviter, quand cas de problème réseaux sur un des serveurs, que le noeud restant ne se voit autonome et bloque les requêtes.

Pour voir si le noeud du cluster est prêt à recevoir des requêtes :

mysql -e"show status like 'wsrep_ready'"

Pour voir plus en détail l’état du cluster :

mysql -e"show status like 'wsrep_%'"

Pour la description des variables, voir : http://galeracluster.com/documentation-webpages/galerastatusvariables.html

!! Attention !! Ce cluster ne fonctionne qu’avec des tables InnoDB, la réplication MyISAM n’est qu’en beta et n’est pas fonctionnelle (table non identique sur chaque noeud en cas de « duplicate entry »). Pour l’activer malgré tout :

wsrep_replicate_myisam          = 1

Maj 27/03/14 : Lien mort

Sep 262013
 

Pour modifier le ttl avec un ratio, il faut ajouter un bout de C :
Au début de la configuration :

C{
        #include <string.h>
        #include <stdlib.h>
        void TIM_format(double t, char *p);
        double TIM_real(void);
}C

Dans le vcl_fetch :

if (beresp.ttl > 0s ) {
        C{
                double obj_ttl = VRT_r_beresp_ttl(sp);
                double ratio = 0.9;
                double new_ttl = obj_ttl*ratio;
                VRT_l_beresp_ttl(sp, new_ttl);
        }C
}

Pour vérifier, vous pouvez ajouter la ligne suivante à la fin du vcl_fetch :

set beresp.http.X-Varnish-TTL = beresp.ttl;
Juil 112013
 

Téléchargez l’archive ici :
cacti-0.8.7i.tar.gz

Il comprend des graphs :
– Systèmes personnalisés
– Apache2
– Mysql
– Memcached
– Varnish

Voir http://cacti.net/ pour le détail de l’installation.

– Pour les graphiques apache, il vous faut wget, perl
– Pour les graphiques memcache, il vous faut python, python-memcache
– Pour les graphiques varnish, il faut un utilisateur cacti avec connexions ssh par clé et clé présent ici /etc/apache2/www-data

Maj 11/07/13 :
Nouvelle version 0.8.8a :
cacti-0.8.8a-plustemplates.tar.gz

Templates supplémentaires percona Redis / Nginx / MongoDB / SystèmeLinux
Cron différent : fichier cacti/cron

Fév 072013
 

L’ESI (Edge Side Includes) est supporté par Varnish. C’est un language de balisage HTML permettant d’assembler une page dynamique.
Cela permet de cacher avec différents temps en cache ou de ne pas cacher, différents bloc d’une page.
Par exemple :
ESI
On peut définir le temps de cache avec le header « Cache-Control : max-age » ou directement dans la configuration varnish.
Voici une page d’exemple :
– index.php :

<?php
        header('Cache-Control: max-age=3600');
?>
<title>Page de test ESI</title>
<html><body>
        Cette page est cach&eacute;e pourtant j'arrive &agrave; afficher l'heure :
        <esi:include src="/dyn/date.php"/>
</body></html>

– date.php :

<?php
        header('Cache-Control: max-age=0');
        echo date('Y-m-d H:i:s');
?>

Il faut activer l’ESI dans la configuration varnish :

sub vcl_fetch {
        set beresp.do_esi = true;

Si vous avez un panier, il faut pouvoir identifier les utilisateurs avec une session php.
Si il y a une session php, elle ne peut pas être définit par la page cachée : il faudra donc la générer autrement :

<script type='text/javascript' src="/dyn/sessions.php"></script>

– sessions.php :

<?php
        session_start();
?>

Pour que tous les utilisateurs reçoivent la page commune cachée et qu’elle reste dynamique en fonction des utilisateurs il faut enlever la session des cookies pour les pages/parties communes et la laisser pour les pages/parties individuelles.
Dans la configuration varnish :

if ( ! req.url ~ "^/dyn" ) {
        set req.http.Cookie = regsuball(req.http.Cookie, "PHPSESSID=[^;]+(; )?", "");
        if (req.http.Cookie ~ "^$") {
            unset req.http.Cookie;
        }

On peut tester avec cette page :
– index.php :

<?php
        header('Cache-Control: max-age=3600');
?>
<title>Page de test ESI</title>
<html><body>
        Cette page est cach&eacute;e pourtant j'arrive &agrave; afficher l'heure :
        <esi:include src="/dyn/date.php"/>
        <br>Ainsi que l'ID de session : <esi:include src="/dyn/phpsess.php"/>
        <script type='text/javascript' src="/dyn/sessions.php"></script>
</body></html>

– phpsess.php :

<?php
        header('Cache-Control: max-age=0');
        echo $_COOKIE["PHPSESSID"];
?>

Le résultat : http://blog.jeremm.fr/esi/
A la première visite vous n’avez pas de session, elle ne sera donc pas affichée.

Jan 232013
 

Une configuration basique de varnish :

# Backend par defaut
backend default {
   .host = "127.0.0.1";
   .port = "81";
   .connect_timeout = 1s;
   .first_byte_timeout = 30s;
     .probe = {
        .url = "/";  # ou .request = "GET / HTTP/1.1" "Host: blog.jeremm.fr" "Connection: close";
        .timeout  = 15s;
        .interval = 15s;
        .window    = 5;
        .threshold = 2;
    }
}
 
sub vcl_recv {
   set req.grace = 300s;
   set req.backend = default ;
   if (req.restarts == 0) {
      if (req.http.x-forwarded-for) {
          set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
      } else {
          set req.http.X-Forwarded-For = client.ip;
      }
   }
   if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&
      req.request != "OPTIONS" &&
      req.request != "DELETE") {
        return (pipe);
   }
   if (req.request != "GET" && req.request != "HEAD") {
       return (pass);
   }
   if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|gz|rar|txt|bzip|pdf)(\?.*|)$" && req.url !~ "^/index.php?") {
       unset req.http.Cookie;
       return (lookup);
   }
   if (req.http.Authorization) {
       return (pass);
   }
   return (lookup);
}
 
sub vcl_hash {
        hash_data(req.url);
        if (req.http.host) {
                hash_data(req.http.host);
        } else {
                hash_data(server.ip);
        }
        if (req.http.Cookie) {
                hash_data(req.http.Cookie);
        }
        return(hash);
}
sub vcl_pass {
        set req.http.X-marker = "pass" ;
}
sub vcl_fetch {
        if ( ! beresp.http.Content-Encoding ~ "gzip" ) {
                set beresp.do_gzip = true;
        }
        if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|gz|rar|txt|bzip|pdf)$") {
                unset beresp.http.Set-Cookie;
        }
        if (beresp.ttl > 0s ) {
                  if (beresp.status >= 300 && beresp.status <= 399) {
                        set beresp.ttl = 10m;
                  }
                  if (beresp.status >= 399) {
                        set beresp.ttl = 0s;
                  }
        }
        if (beresp.status >= 399) {
                unset beresp.http.Set-Cookie;
        }
        # Maximum 24h de cache
        if (beresp.ttl > 86400s) {
                set beresp.ttl = 86400s;
        }
        if (req.http.X-marker == "pass" ) {
                unset req.http.X-marker;
                set beresp.http.X-marker = "pass";
                set beresp.ttl = 0s ;
        }
        if (beresp.ttl > 0s && beresp.http.Set-Cookie) {
                set beresp.ttl = 0s ;
        }
}
 
sub vcl_deliver {
        if (obj.hits > 0){
                set resp.http.X-Varnish-Cache = "HIT";
        }else{
                set resp.http.X-Varnish-Cache = "MISS";
        }
        if (resp.http.X-marker == "pass" ) {
                remove resp.http.X-marker;
                set resp.http.X-Varnish-Cache = "PASS";
        }
        remove resp.http.Via;
        remove resp.http.X-Varnish;
        remove resp.http.Server;
        remove resp.http.X-Powered-By;
 }
 
sub vcl_error {
        if (obj.status >= 500 && req.restarts < 4) {
                return (restart);
        }
}

Pour télécharger directement le fichier default.vcl : default.vcl

Pour les options de démarrage : Configuration et optimisation du daemon Varnish

Maj 06/03/12 : ajout du X-marker pass
Maj 16/04/12 : ajout req.grace
Maj 19/08/12 : téléchargement du fichier default.vcl / don’t hash Accept-Encoding
Maj 03/09/12 : unset set-cookie sur media, pas de unset cookie sur media commençant par /index.php?, unset Set-cookie sur 404
Maj 23/01/13 : add set beresp.do_gzip = true ;