<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Decrypt &#187; Load Balancing</title>
	<atom:link href="http://decrypt.ysance.com/category/architecture/load-balancing/feed/" rel="self" type="application/rss+xml" />
	<link>http://decrypt.ysance.com</link>
	<description>Le site de decryptage des technologies de l&#039;informatique</description>
	<lastBuildDate>Fri, 03 Feb 2012 08:25:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Le Web accélère avec Varnish !!!</title>
		<link>http://decrypt.ysance.com/2012/02/le-web-accelere-avec-varnish/</link>
		<comments>http://decrypt.ysance.com/2012/02/le-web-accelere-avec-varnish/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 19:42:44 +0000</pubDate>
		<dc:creator>Laurent Roux</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Haute Disponibilité]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[NCSA]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[Syslog-NG]]></category>
		<category><![CDATA[Varnish]]></category>

		<guid isPermaLink="false">http://decrypt.ysance.com/?p=2756</guid>
		<description><![CDATA[<img class="size-full wp-image-2795 alignright" title="Varnish Cache" src="http://decrypt.ysance.com/wp-content/uploads/2012/01/varnish_cache.jpg" alt="Varnish Cache" width="192" height="192" /><a title="Site de Varnish Cache" href="http://www.varnish-cache.org/" target="_blank">Varnish</a> est un outil fabuleux à bien des égards. C’est une boite à outils qui permet de simplifier, harmoniser, sécuriser et accélérer les architectures web. Nous allons aborder dans cet article certaines fonctionnalités de Varnish pour commencer à en tirer le maximum. Il se positionne comme un reverse proxy cache. En gros nous allons le placer en amont des serveurs Web pour intercepter les requêtes, mettre en cache ce qui est généré par les backends et resservir le contenu généré depuis son cache. Mais son fonctionnement peut aller plus loin.

<em><strong>Le fonctionnement</strong></em>
Varnish se configure simplement grâce à deux types de fichiers. Le fichier de configuration de Varnish où nous allons définir certains paramètres internes et les fichiers VCL qui permettent de configurer le comportement de Varnish via une sorte de langage de programmation.

[...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-2795 alignright" title="Varnish Cache" src="http://decrypt.ysance.com/wp-content/uploads/2012/01/varnish_cache.jpg" alt="Varnish Cache" width="192" height="192" /><a title="Site de Varnish Cache" href="http://www.varnish-cache.org/" target="_blank">Varnish</a> est un outil fabuleux à bien des égards. C’est une boite à outils qui permet de simplifier, harmoniser, sécuriser et accélérer les architectures web. Nous allons aborder dans cet article certaines fonctionnalités de Varnish pour commencer à en tirer le maximum. Il se positionne comme un reverse proxy cache. En gros nous allons le placer en amont des serveurs Web pour intercepter les requêtes, mettre en cache ce qui est généré par les backends et resservir le contenu généré depuis son cache. Mais son fonctionnement peut aller plus loin.</p>
<p>&nbsp;</p>
<h3>Le fonctionnement</h3>
<p>Varnish se configure simplement grâce à deux types de fichiers. Le fichier de configuration de Varnish où nous allons définir certains paramètres internes et les fichiers VCL qui permettent de configurer le comportement de Varnish via une sorte de langage de programmation.</p>
<p><a title="Le principe de Varnish" href="https://www.varnish-cache.org/trac/wiki/VCLExampleDefault" target="_blank">Le principe de Varnish</a> s’appuie sur la machine à état suivante :</p>
<p style="text-align: center;"><img class="aligncenter size-large wp-image-2761" title="VCL" src="http://decrypt.ysance.com/wp-content/uploads/2012/01/vcl-649x1024.png" alt="VCL" width="649" height="1024" /></p>
<p>&nbsp;</p>
<p>Varnish permet d’intervenir au niveau de chacun des états pour effectuer des opérations sur HTTP ou sur lui-même. C’est cette finesse d’intervention qui permet à Varnish d’être véloce et complet.</p>
<p>Un client effectue une requête sur une ressource qui n’est pas en cache suivra le cheminement suivant :<br />
<img class="size-full wp-image-2804" title="Varnish cache miss" src="http://decrypt.ysance.com/wp-content/uploads/2012/01/cache_miss.png" alt="Varnish cache miss" width="532" height="109" /><br />
Si cette ressource est demandée à nouveau, le chemin suivi change car la ressource est maintenant en cache :<br />
<img class="size-full wp-image-2806" title="Varnish cache hit" src="http://decrypt.ysance.com/wp-content/uploads/2012/01/cache_hit.png" alt="Varnish cache hit" width="404" height="116" /></p>
<p>Toutes ces étapes sont symbolisées en VCL par des “procédures standards” (vcl_recv, vcl_fetch, vcl_deliver&#8230; etc). Toutes ces procédures sont surchargables et nous pouvons aussi déclarer les nôtres qui seront appelées dans les procédures standards. Le langage VCL ne tolère aucun code orphelin, tout ce qui est déclaré doit être utilisé.</p>
<p>&nbsp;</p>
<h3>Le Cache</h3>
<p>Varnish propose un cache en mémoire et un cache sur disque. Mais il faut faire un choix, les deux ne sont pas cumulables. Le cache accepte à peu près tout ce qui passe dans les mains de Varnish (pages HTML, fichiers statics, flux de données en JSON&#8230; etc), à partir du moment où l’on déclare l’objet cachable et qu’il a une TTL.<br />
Le cache est alimenté juste après l’étape “Fetch”, en réalité c’est juste après la récupération de la donnée sur le backend. C’est à cet endroit que l’on va faire toutes les modifications de l’entête HTTP de la ressource cachée. Faire ces modifications au niveau du “Fetch” va permettre de garantir une entrée cache propre (ne pas avoir plusieurs entrées cache car une même ressource va avoir un payload différent). De plus l’objet est stocké dans le cache avec son entête HTTP, il est donc plus efficace de traiter une fois pour toute l’entête et la resservir avec l’objet.<br />
Comme nous le verrons plus loin, la compression d’objet influe aussi sur les performances du cache. Il est préférable de stocker un objet compressé et laisser Varnish le délivrer compressé ou non suivant l’entête “Accept-Encoding”.</p>
<p>La définition correct de la TTL d’un objet pour manager le cache-control est un élément important de Varnish. Nous pouvons contrôler le cache de façon précise en définissant la TTL pour un type de ressource ou pour une url par exemple :</p>
<blockquote>
<pre>if(beresp.ttl &gt; 0s){
  unset beresp.http.Expires;
  if ( req.backend == backend_S3 ) {
     set beresp.http.Cache-Control = "public, max-age=60";
     set beresp.ttl = 60s;
  } else {
     set beresp.http.Cache-Control = "public, max-age=7200";
     set beresp.ttl = 2h;
  }
}</pre>
</blockquote>
<p>Ici nous demandons à Varnish de cacher sur 60 secondes tout ce qui vient de le backend “backend_S3” et le reste sera caché deux heures.</p>
<p>Le cache peut se manager de deux façons différentes :</p>
<li>Via des appels HTTP par la méthode PURGE et en gérant des ACLs pour sécuriser l’appel.</li>
<li>Via les “Bans” que l’on peut inclure dans le VCL ou effectuer via varnishadm.</li>
<p>&nbsp;</p>
<h3>La Compression</h3>
<p>Depuis la version 3.0, Varnish a la possibilité de compresser et décompresser des ressources. Cette fonctionnalité est importante pour 3 raisons :</p>
<li>Économiser de la bande passante entre le backend et Varnish.</li>
<li>Économiser de la place dans le cache de Varnish surtout quand il est en mémoire.</li>
<li>Économiser de la bande passante entre Varnish et le Client.</li>
<p>Elle peut être activée simplement en harmonisant l’entête “Accept-Encoding” et en positionnant la variable “do_gzip” au niveau du backend ou de la réponse du backend. Pour le reste Varnish va adapter la réponse (objet compressé ou non) au client en s’appuyant sur le “Accept encoding” de la requête.<br />
Il est bien sûr évident que la stratégie de compression doit être adaptée au type d’objet. On ne compressera pas un objet déjà compressé (gif, jpg&#8230;etc) :).</p>
<p>&nbsp;</p>
<h3>Le Loadbalancing</h3>
<p>Varnish peut gérer des backends de tous horizons. Avec des sites de plus en plus chargés, il est capable d’offrir la possibilité de faire du loadbalancing. Varnish dispose de 3 types de loadbalancing qui sont appelés “Director” :</p>
<li>RoundRobin.</li>
<li>Client (permet de faire du sticky session sur n’importe quel élément du header).</li>
<li>Random (disponible&#8230; utile c’est une autre histoire).</li>
<p>Varnish sait gérer l’éviction d’un backend lorsqu’il est indisponible. Cette fonctionnalité est d’autant plus utile quand nous activons le “probe” sur les backends.</p>
<blockquote>
<pre>backend server1 {
   .host = "server1.example.com";
   .probe = {
     .url = "/";
     .interval = 5s;
     .timeout = 1s;
     .window = 5;
     .threshold = 3;
   }
}</pre>
</blockquote>
<p>Varnish dispose aussi d’un mécanisme pour palier complètement à la défaillance d’un backend ou d’un Director. Nous appelons cela “Grace mode” ou “Saint mode”. Ces termes cachent la possibilité de servir un contenu caché même x minutes après la TTL en cas de non réponse d&#8217;un serveur. Il est aussi capable d’aiguiller une requête vers un autre serveur répondant correctement quand le serveur cible initial donne des réponses HTTP 500 à cause d’une trop grande charge par exemple.</p>
<p>&nbsp;</p>
<h3>Reverse Proxy</h3>
<p>Nous avons vu que Varnish se place devant toute notre infrastructure. Il va permettre de masquer complètement l’architecture déployée en utilisant toute la puissance de Reverse Proxy qu’il met à notre disposition.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-2765" title="Reverse Proxy" src="http://decrypt.ysance.com/wp-content/uploads/2012/01/Varnish1.png" alt="Reverse Proxy" width="382" height="370" /></p>
<p>En fait, il nous permet de faire un découplage complet entre l’organisation des URIs d’appels et l’organisation de leurs traitements sur l’infrastructure.</p>
<p>Voici un exemple d’une requête cliente que nous arrivons à aiguiller avec Varnish vers un bucket S3 public du nom de “ressources” et l’aiguillage prend en compte ce qu’il y a dans le nom du host de la requete :</p>
<blockquote>
<pre>set req.backend = backend_s3;
if(req.url == "/ressources1.xml") {
  set req.url = regsuball(req.http.host,
              "^(?:.*[.])?([a-z]+)[.](?:net|com)$", "/ressource1.\1.xml");
}else if(req.url == "/ressource2.txt") {
  set req.url = regsuball(req.http.host,
              "^(?:([a-z]+)[0-9]*[.])(?:([a-z]+)*[.])[a-z]+$","/ressources.\1.\2.txt");
}
set req.http.host = "resources.s3.amazonaws.com";

backend  backend_s3 {
  .host = "ressources.s3.amazonaws.com";
  .port = "80";
  .connect_timeout = 5s;
  .first_byte_timeout = 3s;
  .between_bytes_timeout = 2s;
  .max_connections = 1000;
}</pre>
</blockquote>
<p>&nbsp;</p>
<h3>Sécuriser et nettoyage HTTP</h3>
<p>Le protocole HTTP permet d’utiliser plusieurs types de méthodes (GET, POST, DELETE&#8230; etc). Ces méthodes peuvent être utilisées de différentes manières pour déclencher des actions spécifiques (cas de services REST) sur les services abrités sur les backends. Or la protection au niveau HTTP de ce genre de services est assez fastidieuse côté serveurs d’applications. Varnish va permettre de filtrer précisément ce qui doit passer et pour quelle utilisation. Nous allons donc limiter les effets de bords.<br />
Imaginons que nous avons un service accessible uniquement en GET /service1/ et un deuxième /service2/ accessible lui en GET et POST nous allons écrire quelque chose comme ceci :</p>
<blockquote>
<pre>if (req.request != "GET" &amp;&amp; req.request != "POST"){
  call error;
}

if (req.url ~ "^/service2"){
call service2;
}

if(req.request == "POST"){
  call error;
}

if (req.url ~ "^/service1"){
  call service1;
}

call error;</pre>
</blockquote>
<p>Dans cet exemple nous interdisons systématiquement tout ce qui n’est pas méthode GET ou POST. Ensuite pour une url qui commence par /service2 nous allons vers la routine qui va traiter le payload pour ce service. Puis nous bannissons la méthode POST et nous traitons les urls avec /service1 et enfin nous bannissons le reste.</p>
<p>Avec cette méthode aucune requête non prévue peut remonter vers un backend. Nous avons deux avantages :</p>
<li>Le code pour traiter les cas aux limites sera plus simple.</li>
<li>Une majorité d’erreurs ne remonteront pas vers le backend, celles-ci ne provoqueront donc aucune exception ni saturation.</li>
<p>Dans un deuxième cas de figure il peut être intéressant de normaliser les entêtes HTTP. Prenons l’exemple de l’Accept-Encoding. Varnish préconise de le normaliser ainsi :</p>
<blockquote>
<pre>if (req.http.Accept-Encoding) {
  if (req.http.Accept-Encoding ~ "gzip") {
    set req.http.Accept-Encoding = "gzip";
  } elsif (req.http.Accept-Encoding ~ "deflate") {
    set req.http.Accept-Encoding = "deflate";
  } else {
    remove req.http.Accept-Encoding;
  }
}</pre>
</blockquote>
<p>Tout simplement pour éviter de créer des entrées cache différentes pour un même payload uniquement parce que tous les clients n’écrivent pas cet entête de la même façon.</p>
<p>Nous pouvons aussi enlever certains headers qui peuvent donner trop d’informations sur l’infrastructure. Pour S3 par exemple nous allons passer ces commandes dans le fetch :</p>
<blockquote><p>unset beresp.http.x-amz-id-2;<br />
unset beresp.http.x-amz-request-id;<br />
unset beresp.http.x-amz-meta-s3cmd-attrs;<br />
unset beresp.http.x-amz-meta-s3fox-filesize;<br />
unset beresp.http.x-amz-meta-s3fox-modifiedtime;</p></blockquote>
<p>Ou positionner des entêtes plus personnelles :</p>
<blockquote><p>set beresp.http.Server = &laquo;&nbsp;ServeurPerso&nbsp;&raquo;;</p></blockquote>
<p>La dernière petite chose à penser pour le nettoyage réside dans le positionnement d’un content-type correct pour toutes des ressources. Cette opération se fait de la même manière que pour le nettoyage des headers en positionnant “set beresp.http.Content-Type” par groupe de ressources.</p>
<p>De par ces fonctionnalités, Varnish est capable d&#8217;assurer l&#8217;orchestration de la haute disponibilité d&#8217;une architecture. Il est capable de détecter les backends défaillants et même de les remplacer en s&#8217;appuyant sur son cache. Il va les protéger en prenant en compte une grande partie de la gestion des erreurs 404.</p>
<p>&nbsp;</p>
<h3>Uniformisation des Logs d’accès</h3>
<p>Le process “varnishd” ne produit aucun log. Il se contente d’écrire les informations dans des segments de mémoire partagée. Ces segments sont consommés par des outils comme varnishadm, varnishlog ou encore varnishncsa. C’est principalement varnishncsa qui nous intéresse. C’est ce process qui va lire les informations et créer un fichier de log au format NCSA. L’avantage ici est énorme. Nous pouvons décharger les serveurs d’applications et front http de la production de ces logs. De plus ces logs seront moins éparpillés (quoi que, avec l’utilisation de <a title="syslog-ng" href="http://www.balabit.com/sites/default/files/documents/syslog-ng-v3.0-guide-admin-en.html/bk01-toc.html" target="_blank">syslog-ng</a> ça ne soit pas un problème). Enfin les logs seront tous normalisés qu&#8217;ils soient sur Apache, Tomcat, JBoss ou encore lighttp et NginX. Nous pouvons donc penser uniquement aux traitements que nous allons bien pouvoir leur faire subir et ne plus passer du temps à tout reformater. Cette considération prend tout son sens quand on commence à atteindre plusieurs gigas de logs d’accès par jour.<br />
Depuis la version 3.0, Varnishncsa permet de ne pas suivre la norme NCSA et nous laisse le choix du format de sortie.</p>
<p><em><strong>Laurent ROUX</strong></em></p>
]]></content:encoded>
			<wfw:commentRss>http://decrypt.ysance.com/2012/02/le-web-accelere-avec-varnish/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finalement Cohérent &#8211; Revisité</title>
		<link>http://decrypt.ysance.com/2011/04/finalement-coherent-revisite/</link>
		<comments>http://decrypt.ysance.com/2011/04/finalement-coherent-revisite/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 15:51:52 +0000</pubDate>
		<dc:creator>Werner Vogels</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Haute Disponibilité]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Systèmes Distribués]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[Cohérence]]></category>
		<category><![CDATA[Consistance]]></category>
		<category><![CDATA[Dynamo]]></category>

		<guid isPermaLink="false">http://decrypt.ysance.com/?p=2188</guid>
		<description><![CDATA[<em>J’ai écrit une <a title="All Things Distributed, Eventually Consistent" href="http://www.allthingsdistributed.com/2007/12/eventually_consistent.html">première version de cet article</a> au sujet des modèles de cohérence il y a environ un an, mais je n’en étais jamais très content, car il a été rédigé à la hâte, et le sujet est suffisamment important pour mériter un traitement plus approfondi. <a title="Site de ACM Queue" href="http://queue.acm.org/issuedetail.cfm?issue=1466443">ACM Queue</a> m’a demandé de réviser l’article afin de le publier dans leur revue, et j’ai profité de cette occasion pour l’améliorer. La nouvelle version suit :</em>

<strong>Finalement Cohérent – Construire des systèmes distribués et fiables à l'échelle mondiale exige des compromis entre la cohérence et la disponibilité.</strong>

À la base du Cloud Computing de Amazon se trouvent des services d'infrastructure tels S3 (Simple Storage Service) de Amazon, SimpleDB, et EC2 (Elastic Compute Cloud), qui fournissent des ressources pour la construction de plateformes de calcul à l’échelle d’Internet et d'une large gamme d’applications. Les exigences imposées aux dits services en infrastructure sont très strictes : ils doivent afficher de bonnes notes dans les domaines de la sécurité, la scalabilité, la disponibilité, la performance et la rentabilité, et ils doivent satisfaire ces besoins tout en desservant des millions de clients dans le monde, de façon continue.

Sous les couvertures, ces services sont des systèmes distribués colossaux qui opèrent à l'échelle mondiale. Cette échelle crée des défis supplémentaires, car quand un système traite des trillions et des trillions de requêtes, des évènements qui ont habituellement une probabilité d’occurrence faible sont désormais certains de se produire, ce qu’il faut prendre en compte dès le début lors de la conception et dans l’architecture du système. Etant donné l’étendue mondiale de ces systèmes, nous utilisons des techniques de réplication partout afin de garantir une performance cohérente et une haute disponibilité. Bien que la réplication nous rapproche de nos objectifs, elle ne peut les atteindre de façon parfaitement transparente ; sous plusieurs conditions, les clients de ces services seront confrontés avec les conséquences d’avoir utilisé des techniques de réplication au sein des services.

[...]
]]></description>
			<content:encoded><![CDATA[<p><em>J’ai écrit une <a title="All Things Distributed, Eventually Consistent" href="http://www.allthingsdistributed.com/2007/12/eventually_consistent.html">première version de cet article</a> au sujet des modèles de cohérence il y a environ un an, mais je n’en étais jamais très content, car il a été rédigé à la hâte, et le sujet est suffisamment important pour mériter un traitement plus approfondi. <a title="Site de ACM Queue" href="http://queue.acm.org/issuedetail.cfm?issue=1466443">ACM Queue</a> m’a demandé de réviser l’article afin de le publier dans leur revue, et j’ai profité de cette occasion pour l’améliorer. La nouvelle version suit :</em></p>
<p><strong>Finalement Cohérent – Construire des systèmes distribués et fiables à l&#8217;échelle mondiale exige des compromis entre la cohérence et la disponibilité.</strong></p>
<p>À la base du Cloud Computing de Amazon se trouvent des services d&#8217;infrastructure tels S3 (Simple Storage Service) de Amazon, SimpleDB, et EC2 (Elastic Compute Cloud), qui fournissent des ressources pour la construction de plateformes de calcul à l’échelle d’Internet et d&#8217;une large gamme d’applications. Les exigences imposées aux dits services en infrastructure sont très strictes : ils doivent afficher de bonnes notes dans les domaines de la sécurité, la scalabilité, la disponibilité, la performance et la rentabilité, et ils doivent satisfaire ces besoins tout en desservant des millions de clients dans le monde, de façon continue.</p>
<p>Sous les couvertures, ces services sont des systèmes distribués colossaux qui opèrent à l&#8217;échelle mondiale. Cette échelle crée des défis supplémentaires, car quand un système traite des trillions et des trillions de requêtes, des évènements qui ont habituellement une probabilité d’occurrence faible sont désormais certains de se produire, ce qu’il faut prendre en compte dès le début lors de la conception et dans l’architecture du système. Etant donné l’étendue mondiale de ces systèmes, nous utilisons des techniques de réplication partout afin de garantir une performance cohérente et une haute disponibilité. Bien que la réplication nous rapproche de nos objectifs, elle ne peut les atteindre de façon parfaitement transparente ; sous plusieurs conditions, les clients de ces services seront confrontés avec les conséquences d’avoir utilisé des techniques de réplication au sein des services.</p>
<p>Une des façons par laquelle cela se manifeste est dans le type de cohérence des données fournie, surtout quand le système distribué sous-jacent fournit un modèle de cohérence à terme pour la réplication de données. Lors de la conception de ces systèmes à grande échelle chez Amazon, nous utilisons un jeu de principes et d’abstractions directeurs liés à la réplication de données à grande échelle et nous nous focalisons sur les compromis entre la haute disponibilité et la cohérence des données. Dans cet article je présente une partie du contexte pertinent qui a servi de socle à notre approche pour délivrer des systèmes distribués fiables qui doivent opérer à grande échelle. Une <a title="All Things Distributed, Eventually Consistent" href="http://www.allthingsdistributed.com/2007/12/eventually_consistent.html">version antérieure de ce texte</a> a été publiée sur le blog <em>All Things Distributed</em> en décembre 2007, et a été beaucoup améliorée grâce à l’aide de ses lecteurs.</p>
<p><strong>Une Perspective Historique </strong></p>
<p>Dans un monde idéal, il n’y aurait qu’un modèle de cohérence : à chaque fois qu’une mise à jour est faite, tous les observateurs la verraient. La première fois que ceci s’est avéré difficile était dans les systèmes de bases de données de la fin des années 70. La meilleure &laquo;&nbsp;œuvre historique&nbsp;&raquo; sur ce sujet est &laquo;&nbsp;<em>Notes on Distributed Databases</em>&nbsp;&raquo; , par  <a href="http://acmqueue.com/modules.php?name=Content&amp;pa=showpage&amp;pid=233">Bruce Lindsay et al</a>. <sup>5</sup> Elle expose les principes fondamentaux de la réplication de bases de données et examine un certain nombre de techniques qui traitent de la réalisation de la cohérence. Plusieurs de ces techniques tentent d&#8217;obtenir la transparence de la distribution &#8211; c&#8217;est-à-dire que, pour l’utilisateur du système, il semble qu’il n’y ait qu’un seul système, au lieu d&#8217;un certain nombre de systèmes collaboratifs. Plusieurs systèmes pendant cette époque ont adopté l&#8217;approche qu&#8217;il était préférable de désactiver le système entier plutôt que de rompre cette transparence.<sup>2</sup></p>
<p>Au milieu des années 90, avec l’essor de systèmes d’Internet plus importants, ces pratiques ont été revues. A cette époque, les gens commençaient à considérer l&#8217;idée que la disponibilité était peut-être la propriété la plus importante de ces systèmes, mais ils avaient du mal à décider avec quoi ils pourraient faire le compromis. <a href="http://www.cs.berkeley.edu/~brewer/">Eric Brewer</a>, professeur de systèmes à l’Université de Berkeley en Californie, et à l’époque le directeur de Inktomi, a réuni différents compromis dans son <a href="http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf">discours d’ouverture à la conférence PODC</a> (<em>Principles of Distributed Computing</em>) en 2000.<sup>1</sup> Il a présenté le théorème CAP, qui dit que sur les trois propriétés des systèmes de données partagées – la cohérence des données, la disponibilité du système et la tolérance au partitionnement du réseau – seules deux peuvent être garanties à un moment donné. Une confirmation plus formelle se trouve dans un article publié en 2002 par <a href="http://portal.acm.org/citation.cfm?doid=564585.564601">Seth Gilbert et Nancy Lynch</a>.<sup>4</sup></p>
<p>Un système qui n’est pas tolérant aux partitionnements du réseau peut obtenir la cohérence et la disponibilité des données et le réalise souvent via l’utilisation des protocoles de transaction. Afin d’y parvenir, les systèmes client et de stockage doivent faire partie du même environnement : ils échouent comme un ensemble sous certains scénarios, et à ce titre, les clients ne peuvent observer des partitions. Une observation importante est que dans des systèmes distribués à plus grande échelle, les partitionnements du réseau sont un fait ; ainsi, la cohérence et la disponibilité ne peuvent être obtenues en même temps. Cela veut dire qu’il y a deux choix concernant ce que l’on peut laisser tomber : relâcher la cohérence permettra au système de rester hautement disponible sous les conditions du partitionnement, tandis que privilégier la cohérence veut dire que, sous certaines conditions, le système ne sera pas disponible.</p>
<p>Toutes les deux options exigent que le développeur client soit au courant de ce qu&#8217;offre le système. Si le système accentue la cohérence, le développeur doit tenir compte du fait que le système pourrait ne pas être disponible pour accepter par exemple une écriture. Si cette écriture échoue à cause de l’indisponibilité du système, alors le développeur devra décider ce qu’il faut faire des données qui restent à écrire. Si le système souligne la disponibilité, il pourra toujours accepter l’écriture, mais sous certaines conditions une lecture ne reflétera pas le résultat d’une écriture récemment complétée. Le développeur doit décider alors si le client a besoin d’accéder à la toute dernière mise à jour tout le temps. Il existe une gamme d&#8217;applications qui gèrent bien des données légèrement périmées, et elles sont bien desservies sous ce modèle.</p>
<p>En principe, la propriété de cohérence des systèmes de transactions telle que définie par les propriétés <a href="http://en.wikipedia.org/wiki/ACID">ACID</a> (atomicité, cohérence, isolation, durabilité) est une sorte de garantie de cohérence différente. En ACID, la cohérence se rapporte à la garantie que quand une transaction est terminée, la base de données est dans un état cohérent ; par exemple, lors du transfert d&#8217;argent d&#8217;un compte à un autre, le montant total contenu dans les deux comptes ne devra pas changer. Dans des systèmes basés sur ACID, ce genre de cohérence est souvent la responsabilité du développeur qui écrit la transaction mais elle peut être appuyée par la gestion des contraintes d’intégrité par la base de données.</p>
<p><strong>La Cohérence - Client et Serveur</strong></p>
<p>Il existe deux perspectives sur la cohérence. L’une du point de vue développeur<em>/</em>client : comment ils observent les mises à jour des données. L’autre du côté du serveur : comment les mises à jour circulent dans le système et quelles garanties peuvent donner les systèmes concernant les mises à jour.</p>
<p><strong>La Cohérence Client </strong></p>
<p>La cohérence client comporte les éléments suivants :</p>
<ul>
<li><strong>Un système de stockage.</strong> Pour l’instant on peut le considérer comme une simple      boîte noire, mais on devrait supposer que, sous son couvercle, il y a quelque chose à grande échelle et hautement distribué, et qu’il a été construit afin de garantir la durabilité et la disponibilité.</li>
<li><strong>Le processus A.</strong> C’est un processus qui effectue les écritures sur et les lectures à      partir du système de stockage.</li>
<li><strong>Les processus B et C.</strong> Ces deux processus sont indépendants du processus A, et      ils effectuent des écritures sur et des lectures à partir du système de stockage. C’est sans importance si      ce sont réellement des processus, ou plutôt des threads au sein du même processus ; ce qui compte est qu&#8217;ils sont indépendants et qu’ils doivent communiquer afin de partager des informations.<br />
La cohérence côté client concerne comment et quand des observateurs (en l’occurrence les processus A, B, ou C) voient les mises à jour effectuées sur un objet de données dans les systèmes de stockage. Dans les exemples suivants qui illustrent les différents types de cohérence, le processus A a effectué une mise à jour sur un objet de données :</li>
<li><strong>La cohérence forte.</strong> Après que la mise à jour soit terminée, tout accès suivant      (par A, B, ou C) renverra la valeur actualisée.</li>
<li><strong>La cohérence faible.</strong> Le système ne garantit pas que les accès ultérieurs renverront la valeur actualisée. Un certain nombre de conditions doivent être respectées avant que la valeur ne soit renvoyée. La période entre la mise à jour et l’instant où il est garanti que tout observateur verra toujours la valeur actualisée se nomme <em>la fenêtre d’incohérence.</em></li>
<li><strong>La cohérence à terme.</strong> C’est une forme spécifique de cohérence faible ; le      système de stockage garantit que si aucune nouvelle mise à jour n’est effectuée sur l&#8217;objet, tous les accès finiront par renvoyer la dernière valeur actualisée.  Si aucun échec ne se produit, la taille maximale de la fenêtre d’incohérence peut être établie sur la base d&#8217;éléments tels les délais de communication, la charge sur le système et le nombre de répliques concernés par le schéma de réplication. Le système le plus répandu qui      implémente la cohérence à terme est le DNS (<em>Domain Name System</em>). Les mises à jour d’un nom sont distribuées selon un modèle configuré et en association avec des caches à expiration; à terme, tous les clients finiront par voir la mise à jour.</li>
</ul>
<p>Le modèle de cohérence à terme a un nombre de variations qu’il est important de considérer:</p>
<ul>
<li><strong>La cohérence causale <em>(causal consistency)</em>.</strong> Si le processus A a communiqué au processus B qu’il a mis à jour un objet de données, un accès ultérieur par le processus B renverra la valeur actualisée, et une écriture est garantie de remplacer l&#8217;écriture antérieure. Un accès via le processus C qui n’a pas de relation causale avec le processus A est sujet aux règles de cohérence à terme normales.</li>
<li><strong>La cohérence « lecture de vos écritures » (<em>read-your-writes consistency</em>).</strong> C’est un modèle important où le processus A, après qu’il a mis à jour un objet de données,      accède toujours à la valeur actualisée et ne verra jamais une valeur antérieure. C&#8217;est un cas particulier du modèle de cohérence causale.</li>
<li><strong>La cohérence par session (<em>session consistency</em>).</strong> Ceci est une version pratique du modèle précédent, où un processus accède au système de stockage dans le cadre d’une session. Tant que la session existe, le système garantit la cohérence « lecture de vos écritures ». Si la session se termine à cause d’un scénario d&#8217;échec quelconque, une nouvelle session doit être créée, et les garanties ne recouvrent pas les sessions.</li>
<li><strong>La cohérence monotonique en lecture.</strong> Si un processus a vu une valeur      particulière pour l’objet, tout accès ultérieur ne renverra jamais une valeur antérieure.</li>
<li><strong>La cohérence monotonique en écriture.</strong> Dans ce cas, le système garantit de      sérialiser les écritures par le même processus. Les systèmes qui ne garantissent pas ce niveau de cohérence sont notoirement difficiles à programmer.</li>
</ul>
<p>Un certain nombre de ces propriétés peuvent être associées les unes aux autres. Par exemple, on peut obtenir des lectures monotoniques associées à la cohérence par session. D’un point de vue pratique, ces deux propriétés (lectures monotoniques et « lecture de vos écritures ») sont tout à fait souhaitables dans un système de cohérence à terme, mais pas toujours exigées. Ces deux propriétés rendent plus simple pour les développeurs de construire des applications, tout en permettant au système de stockage de relâcher la cohérence et fournir une haute disponibilité.</p>
<p>Comme vous le voyez dans ces variations, un assez grand nombre de scénarios sont possibles. Tout dépend des applications spécifiques, si l’on peut gérer les conséquences ou non.</p>
<p>La cohérence à terme n’est pas une sorte de propriété ésotérique des systèmes distribués extrêmes. Beaucoup de RDBMSs (relational database management systems &#8211; systèmes de gestion de bases de données relationnelles) modernes qui fournissent de la fiabilité au niveau du backup principal implémentent leurs techniques de réplication tant en mode synchrone qu’asynchrone.  En mode synchrone, la mise à jour de la réplique fait partie de la transaction. En mode asynchrone, les mises à jour arrivent au backup de manière différée, souvent par l’exportation du log. En ce dernier mode, si le principal échoue avant l’exportation des logs, la lecture du backup promu produira des valeurs anciennes et incohérentes. Aussi, afin de supporter une meilleure performance scalable en lecture, les RDBMSs ont commencé à fournir la possibilité de lire à partir du backup, ce qui est un cas classique de fourniture de garanties de cohérence à terme dans lesquelles les fenêtres d’incohérence dépendent de la périodicité de l’exportation des logs.</p>
<p><strong>La Cohérence Serveur </strong></p>
<p>Pour la cohérence serveur, il nous faut regarder de plus près comment les mises à jour circulent dans le système afin de comprendre ce qui pilote les différents modes que peut rencontrer le développeur qui utilise le système. Etablissons d’abord quelques définitions avant de commencer :</p>
<p>N = le nombre de nœuds qui stockent les répliques des données</p>
<p>W = le nombre de répliques qui doivent accuser réception de la mise à jour avant que celle-ci ne soit complétée</p>
<p>R = le nombre de répliques qui sont contactées quand un objet de données est consulté via une opération de lecture</p>
<p>Si W+R &gt; N, alors le jeu d’écritures et le jeu de lectures se recouvrent toujours et l’on peut garantir une cohérence forte. Dans le scénario de backup principal de RDBMS qui implémente de la réplication synchrone, N=2, W=2 et R=1. Qu’importe la réplique à partir de laquelle lit le client, il recevra toujours une réponse cohérente. Dans la réplication asynchrone quand la lecture du backup est activée, N=2, W=1 et R=1. Dans ce cas R+W=N et la cohérence ne peut être garantie.</p>
<p>Le problème de ces configurations, qui sont des protocoles de quorum de base, est que quand le système ne peut écrire sur les W nœuds à cause des échecs, l’opération d’écriture échoue obligatoirement, ce qui marque l’indisponibilité du système. Quand N=3 et W=3 et seulement deux nœuds sont disponibles, le système sera obligé de mettre l&#8217;écriture en échec.</p>
<p>Dans les systèmes de stockage distribué qui doivent fournir de la haute performance ainsi que de la haute disponibilité, le nombre de répliques est en général supérieur à deux. Les systèmes qui se focalisent uniquement sur la tolérance à la panne utilisent souvent N=3 (avec des  configurations W=2 et R=2). Les systèmes qui doivent servir des charges en lecture très élevées répliquent souvent leurs données au-delà de ce qui est requis pour la tolérance à la panne ; N peut être des dizaines, voire des centaines de nœuds, avec R configuré à 1, de telle sorte qu’une seule lecture renverra un résultat. Les systèmes qui s’occupent de la cohérence sont configurés à W=N pour les mises à jour, ce qui peut diminuer la probabilité de la réussite de l’écriture. Une configuration courante pour ces systèmes-là qui sont concernés par la tolérance à la panne mais pas par la cohérence, est d&#8217;utiliser W=1 afin d&#8217;obtenir la durabilité minimale de la mise à jour et ensuite de s’appuyer sur une technique de propagation épidémique dans le but de mettre à jour les autres répliques.</p>
<p>Comment configurer N, W et R dépend de ce qu’est le cas courant et de quel chemin de performance doit d’être optimisé. En R=1 et N=W nous optimisons pour le cas de la lecture, et en W=1 et R=N nous optimisons pour une écriture très rapide. Bien sûr, dans ce dernier, la durabilité n’est pas garantie en la présence d’échecs, et si W &lt; (N+1)/2, il y a la possibilité d’écritures contradictoires quand les jeux d’écritures ne se recouvrent pas.</p>
<p>La cohérence faible/à terme se produit quand W+R &lt;= N, ce qui signifie qu’il y a la possibilité que les jeux en lecture et en écriture ne se recouvriront pas. Si c’est une configuration délibérée et non basée sur un cas d’échec, alors ça n&#8217;a aucun sens de régler R autrement que sur 1.  Il existe deux cas très fréquents où cela se produit : le premier est la réplication à grande échelle pour le scaling en lecture mentionné plus haut ; le second se produit quand l’accès aux données est plus compliqué. Dans un modèle clé-valeur simple, il est facile de comparer des versions afin de déterminer la dernière valeur écrite sur le système, mais dans des systèmes qui renvoient des jeux d’objets, il est plus difficile de déterminer correctement le dernier jeu. Dans la plupart de ces systèmes où le jeu en écriture est plus petit que le jeu de répliques, un mécanisme est en place qui applique les mises à jour aux nœuds restants dans le jeu de répliques via une technique de propagation épidémique (<em>lazy</em>). La période jusqu’à ce que toutes les répliques soient mises à jour s’appelle la fenêtre d’incohérence, comme je l’ai évoquée plus haut. Si W+R &lt;= N, alors le système est vulnérable à la lecture à partir de nœuds qui n&#8217;ont pas encore reçu les mises à jour.</p>
<p>Que les cohérences &laquo;&nbsp;lecture de vos écritures&nbsp;&raquo; (<em>read-your-writes</em>), session et monotonique peuvent être obtenues ou pas, dépend en général de l&#8217;association (<em>stickiness</em>) des clients au serveur qui exécute le protocole distribué pour eux. S’il s’agit du même serveur à chaque fois, il est alors relativement facile de garantir la « lecture de vos écritures » et les lectures monotoniques. Cela rend un peu plus difficile l’équilibrage de charges et la tolérance à la panne, mais c’est une solution simple. L’utilisation de sessions, qui ont de l’affinité (<em>sticky</em>), rend cela explicite et fournit un niveau d’exposition sur lequel les clients peuvent raisonner.</p>
<p>Parfois le client implémente la « lecture de vos écritures » et les lectures monotoniques. En rajoutant des versions aux écritures, le client rejette les lectures de valeurs ayant des versions qui précèdent la version vue en dernier.</p>
<p>Les partitions se produisent quand certains nœuds ne peuvent atteindre d’autres dans le système, mais tous les deux jeux de nœuds sont accessibles par des groupes de clients. Si vous utilisez une approche de type quorum majoritaire classique, alors la partition qui a W nœuds du jeu de répliques peut continuer à prendre des mises à jour pendant que l’autre partition devient indisponible. C&#8217;est également vrai pour le jeu en lecture. Etant donné que ces deux jeux se recouvrent, le jeu minoritaire devient par définition indisponible. Les partitions ne se produisent pas fréquemment, mais ils peuvent s’effectuer entre les datacenters, aussi bien que au sein des datacenters.</p>
<p>Dans certaines applications l’indisponibilité de toute partition est inadmissible, et il est important que les clients qui peuvent accéder à cette partition puissent avancer. Dans ce cas les deux côtés attribuent un nouveau jeu de nœuds de stockage pour recevoir les données, et une opération de fusion est exécutée quand la partition est réparée. Par exemple, chez Amazon, le panier de courses utilise un tel système de <em>write-always</em> (d&#8217;écriture permanente) ; dans le cas d&#8217;une partition, un client peut continuer d’ajouter des articles dans son panier même si le panier d’origine existe toujours dans d’autres partitions. L’application de gestion de panier aide le système de stockage à fusionner les paniers une fois la partition réparée.</p>
<p><strong>Dynamo de Amazon </strong></p>
<p>Un système qui a réuni toutes ces propriétés sous le contrôle explicite de l’architecture de l’application est <a title="All Things Distributed, Amazon's Dynamo" href="http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html">Dynamo de Amazon</a>, un système de stockage clé-valeur qui est utilisé en interne dans plusieurs services qui constituent la plateforme <em>e-commerce</em> (commerce électronique) d’Amazon, ainsi que dans les Amazon&#8217;s Web Services. Un des objectifs de conception de Dynamo est de permettre au propriétaire du service de l&#8217;application qui crée une instance du système de stockage Dynamo &#8211; qui s’étend fréquemment sur de multiples datacenters &#8211; de faire lui-même le compromis entre la cohérence, la durabilité, la disponibilité et la performance, tout en restant à un certain seuil de coût.<sup>3</sup></p>
<p><strong>Conclusion</strong></p>
<p>Il existe deux raisons de tolérer l’incohérence des données dans des systèmes distribués fiables à grande échelle : l’amélioration de la performance en lecture et en écriture dans des conditions hautement concomitantes, et la gestion des cas de partitionnement où un modèle basé sur la majorité rendrait une partie du système indisponible bien que les nœuds soient opérationnels.</p>
<p>Que les incohérences soient admissibles ou non dépend de l’application client. Dans tous les cas le développeur doit savoir que les garanties de cohérence sont fournies par les systèmes de stockage et doivent être prises en compte lorsqu’on développe les applications. Il y a plusieurs améliorations pratiques que l’on peut faire au modèle de cohérence à terme, comme par exemple la cohérence par session<em> </em>et les lectures monotoniques, qui fournissent de meilleurs outils pour le développeur. Très souvent l’application est capable de gérer les garanties de cohérence à terme du système de stockage sans problème. Un cas précis fréquent est un site Web sur lequel on a la notion de la cohérence perçue par l’utilisateur. Dans ce scénario, la fenêtre d’incohérence doit être inférieure au temps estimé avant le retour du client pour le chargement de la page suivante. Ceci permet aux mises à jour de se propager dans le système avant que la lecture suivante ne soit prévue.</p>
<p>Le but de cet article est de sensibiliser le lecteur à la complexité des systèmes d’ingénierie qui doivent opérer à échelle globale et qui exigent un tuning méticuleux afin d’assurer la durabilité, la disponibilité et la performance exigées par leurs applications. L’un des outils du concepteur de systèmes est la durée de la fenêtre d&#8217;incohérence, pendant laquelle les clients des systèmes sont potentiellement exposés aux réalités de l’ingénierie des systèmes à grande échelle.</p>
<p><strong><em>Werner Vogels</em> <a href="http://www.allthingsdistributed.com/">@allthingsdistributed.com</a></strong></p>
<p><em>Source : <a href="http://www.allthingsdistributed.com/2008/12/eventually_consistent.html">Eventually Consistent &#8211; Revisited</a><br />
Traduction : <a href="http://www.proz.com/profile/1185931">Helen CHAUVEAU</a>, <a href="http://twitter.com/fredericfaure">Frédéric FAURE</a></em></p>
<p><em>References :</em></p>
<ol style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.75em; margin-left: 30px; list-style-type: decimal; list-style-position: outside; list-style-image: initial; background-repeat: no-repeat repeat; padding: 0px;">
<li style="padding: 0px; margin: 0px;">Brewer, E. A. 2000. <a style="text-decoration: underline; outline-style: none; outline-width: initial; outline-color: initial; color: #ab0404;" href="http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf">Towards robust distributed systems (abstract)</a>. In <em>Proceedings of the 19th Annual ACM Symposium on Principles of Distributed Computing</em> (July 16-19, Portland, Oregon): 7</li>
<li style="padding: 0px; margin: 0px;"><a style="text-decoration: underline; outline-style: none; outline-width: initial; outline-color: initial; color: #ab0404;" href="http://acmqueue.com/modules.php?name=Content&amp;pa=showpage&amp;pid=233">A Conversation with Bruce Lindsay.</a> 2004. ACM Queue 2(8): 22-33.</li>
<li style="padding: 0px; margin: 0px;">DeCandia, G., Hastorun, D., Jampani, M., Kakulapati, G., Lakshman, A., Pilchin, A., Sivasubramanian, S., Vosshall, P., Vogels, W. 2007. <a style="text-decoration: underline; outline-style: none; outline-width: initial; outline-color: initial; color: #ab0404;" href="http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html">Dynamo: Amazon&#8217;s highly available key-value store</a>. In Proceedings of the 21st ACM <em>Symposium on Operating Systems Principles</em> (Stevenson, Washington, October).</li>
<li style="padding: 0px; margin: 0px;">Gilbert , S., Lynch, N. 2002. <a style="text-decoration: underline; outline-style: none; outline-width: initial; outline-color: initial; color: #ab0404;" href="http://portal.acm.org/citation.cfm?doid=564585.564601">Brewer&#8217;s conjecture and the feasibility of consistent, available, partition-tolerant Web services</a>. ACM SIGACT News 33(2).</li>
<li style="padding: 0px; margin: 0px;">Lindsay, B. G., Selinger, P. G., et al. 1980. Notes on distributed databases. In <em>Distributed Data Bases, ed. I</em>. W. Draffan and F. Poole, 247-284. Cambridge: Cambridge University Press. Also available as IBM Research Report RJ2517, San Jose, California (July 1979).</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://decrypt.ysance.com/2011/04/finalement-coherent-revisite/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Les 9 principes de S3</title>
		<link>http://decrypt.ysance.com/2009/11/les-9-principes-de-s3/</link>
		<comments>http://decrypt.ysance.com/2009/11/les-9-principes-de-s3/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 17:32:16 +0000</pubDate>
		<dc:creator>Frédéric Faure</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Clustering]]></category>
		<category><![CDATA[Haute Disponibilité]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[S3]]></category>

		<guid isPermaLink="false">http://decrypt.ysance.com/?p=652</guid>
		<description><![CDATA[Décidemment, encore un article sur les <a title="Site de Amazon Web Services" href="http://aws.amazon.com/">AWS</a> (Amazon Web Services). Au-delà du fait, que ce sont de bons composants dans le cadre de la mise en place d'une infrastructure, il faut noter qu'ils couvrent un scope complet de ce que l'on peut trouver dans une infrastructure en termes de fonctionnalités (gestionnaire de files de messages -<a title="Site de Amazon Web Services, Rubrique Amazon Simple Queue Service" href="http://aws.amazon.com/sqs/">SQS</a>-, base de données non relationnelle -<a title="Site de Amazon Web Services, Rubrique Amazon SimpleDB" href="http://aws.amazon.com/simpledb/">SimpleDB</a>- et relationnelle -<a title="Site de Amazon Web Services, Rubrique Amazon Relational Database Service" href="http://aws.amazon.com/rds/">RDS</a>- depuis peu, traitement massif de données -<a title="Site de Amazon Web Services, Rubrique Amazon Elastic MapReduce" href="http://aws.amazon.com/elasticmapreduce/">MapReduce</a>, bonjour BI ?-, instances virtuelles -<a title="Site de Amazon Web Services, Rubrique Amazon Elastic Compute Cloud" href="http://aws.amazon.com/ec2/">EC2</a>-, VPN -<a title="Site de Amazon Web Services, Rubrique Amazon Virtual Private Cloud" href="http://aws.amazon.com/vpc/">VPC</a>-, ...), mais également en termes de "background technique". Je m'explique : prenons l'exemple de <a title="Site de Amazon Web Services, Rubrique Amazon Simple Storage Service" href="http://aws.amazon.com/s3/">S3</a>, qui sera notre sujet d'étude dans cet article d'ailleurs, quoi de plus simple qu'un système de stockage d'objets ? Ca se résume à "PUT", "GET" et "DELETE". Et pourtant derrière cette apparente simplicité, se cache une complexité technique sous-jacente étonnante, qui reprend bons nombres de concepts "standards", mais que l'on implémente rarement soi-même, parceque complexes à mettre en place. On laisse donc cela aux outils que l'on utilise ou tout simplement on fait l'impasse dessus. Tout cela pour introduire les 9 principes sous-jacents au service S3 d'Amazon qui font de ce service apparemment succint, un bel exemple technique.

[...]]]></description>
			<content:encoded><![CDATA[<p>Décidemment, encore un article sur les <a title="Site de Amazon Web Services" href="http://aws.amazon.com/">AWS</a> (Amazon Web Services). Au-delà du fait que ce sont de bons composants dans le cadre de la mise en place d&#8217;une infrastructure, il faut noter qu&#8217;ils couvrent un scope complet de ce que l&#8217;on peut trouver dans une infrastructure en termes de fonctionnalités (gestionnaire de files de messages -<a title="Site de Amazon Web Services, Rubrique Amazon Simple Queue Service" href="http://aws.amazon.com/sqs/">SQS</a>-, base de données non relationnelle -<a title="Site de Amazon Web Services, Rubrique Amazon SimpleDB" href="http://aws.amazon.com/simpledb/">SimpleDB</a>- et relationnelle -<a title="Site de Amazon Web Services, Rubrique Amazon Relational Database Service" href="http://aws.amazon.com/rds/">RDS</a>- depuis peu, traitement massif de données -<a title="Site de Amazon Web Services, Rubrique Amazon Elastic MapReduce" href="http://aws.amazon.com/elasticmapreduce/">MapReduce</a>, bonjour BI ?-, instances virtuelles -<a title="Site de Amazon Web Services, Rubrique Amazon Elastic Compute Cloud" href="http://aws.amazon.com/ec2/">EC2</a>-, VPN -<a title="Site de Amazon Web Services, Rubrique Amazon Virtual Private Cloud" href="http://aws.amazon.com/vpc/">VPC</a>-, &#8230;), mais également en termes de &laquo;&nbsp;background technique&nbsp;&raquo;. Je m&#8217;explique : prenons l&#8217;exemple de <a title="Site de Amazon Web Services, Rubrique Amazon Simple Storage Service" href="http://aws.amazon.com/s3/">S3</a>, qui sera notre sujet d&#8217;étude dans cet article d&#8217;ailleurs, quoi de plus simple qu&#8217;un système de stockage d&#8217;objets ? Ca se résume à &laquo;&nbsp;PUT&nbsp;&raquo;, &laquo;&nbsp;GET&nbsp;&raquo; et &laquo;&nbsp;DELETE&nbsp;&raquo;. Et pourtant derrière cette apparente simplicité, se cache une complexité technique sous-jacente étonnante, qui reprend bons nombres de concepts &laquo;&nbsp;standards&nbsp;&raquo;, mais que l&#8217;on implémente rarement soi-même, parceque complexes à mettre en place. On laisse donc cela aux outils que l&#8217;on utilise ou tout simplement on fait l&#8217;impasse dessus. Tout cela pour introduire les 9 principes sous-jacents au service S3 d&#8217;Amazon qui font de ce service apparemment succint, un bel exemple technique.</p>
<p>Je vais me baser pour cela sur une présentation de Simone Brunozzi à laquelle j&#8217;ai assisté au Luxembourg. Cette présentation a également eu lieu à Londres à la &laquo;&nbsp;Storage Expo&nbsp;&raquo;. Cette dernière ayant été filmée, je vous la laisse à disposition afin que vous puissiez voir et écouter Simone en live from London ! ;ob</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="225" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=7330740&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="225" src="http://vimeo.com/moogaloop.swf?clip_id=7330740&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
<p><a href="http://vimeo.com/7330740">Simone Brunozzi presents AWS and Amazon S3 at Storage Expo in London</a> from <a href="http://vimeo.com/user1039336">Simone Brunozzi</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p><img class="size-full wp-image-510" title="Logo AWS" src="http://decrypt.ysance.com/wp-content/uploads/2009/08/logo_aws.gif" alt="Logo AWS" width="164" height="60" /></p>
<p><strong><em>Chapitre I : Redundancy / Redondance</em></strong><br />
La redondance, un moyen efficace d&#8217;assurer la durabilité (pas de perte définitive) et l&#8217;accessibilité (pas de perte temporaire) des données. La redondance consiste donc à dupliquer les informations (objets) que vous stockez sur S3 dans plusieurs zones d&#8217;accessibilité d&#8217;une région donnée. Les zones d&#8217;accessibilité sont en fait des datacenter physiquement séparés dans la périphérie d&#8217;une agglomération donnée et reliés entre eux par un réseau privé. Un certain nombre de précautions sont prises lors de la mise en place de ces datacenters, depuis la vérification que les zones sont non sismiques et non inondables, jusqu&#8217;à l&#8217;alimentation électrique distincte pour chacun de ces datacenter. Les objets sont donc répliqués dans et entre ces datacenters en background (transparent pour l&#8217;utilisateur), ce qui permet d&#8217;assurer qu&#8217;ils seront accessibles, même sur la détérioration temporaire ou permanente desdits objets d&#8217;un datacenter donné (panne de courant sur une grille d&#8217;alimentation, &#8230;).</p>
<p>Cette redondance touche également au domaine de la scalabilité, puisque sur la détection d&#8217;une augmentation des accès sur un objet donné, celui-ci est dupliqué de manière plus importante de façon à répartir la charge sur un pool d&#8217;objets.</p>
<p>Il est à noter que la redondance a un coût et engendre une complexité et donc ne doit être mise en place que lorsque cela est nécessaire. Ce coût et cette complexité sont occultés, dans ce cas, par la simplicité d&#8217;utilisation du service S3 pour l&#8217;utilisateur final (vous et moi ! ;ob).</p>
<p><strong><em>Chapitre II : Retry / Réessai</em></strong><br />
Le réessai est une technique afin de fournir une accessibilité maximale de la donnée et notamment de parer aux inaccessibilités temporaires. Un rejeu de la requête, &laquo;&nbsp;GET&nbsp;&raquo; par exemple, est effectué, de manière à réessayer de rapatrier l&#8217;information. Si cela n&#8217;est pas possible, un nouvel essai est réeffectué, mais un peu plus tard et ainsi de suite, avec un intervalle de temps croissant entre chaque essai de manière à ne pas surcharger le système. La requête peut également être rejouée plus tard. Ce qu&#8217;il est important de noter, c&#8217;est que les requêtes pouvant être rejouées automatiquement par S3 doivent être idempotent, c&#8217;est à dire ne pas avoir d&#8217;influence si elles sont jouées plusieurs fois, voire dans des ordres différents. De manière générale, une requête idempotent ne modifie pas le système cible (donc plutôt des &laquo;&nbsp;GET&nbsp;&raquo;).</p>
<p>Le détail du fonctionnement n&#8217;est évidemment pas divulgué par Amazon et ce que nous voyons là sont les grands principes du fonctionnement du service S3. Cela est confidentiel car, tout d&#8217;abord c&#8217;est leur &laquo;&nbsp;business&nbsp;&raquo;, mais aussi pour des questions de sécurité, évidemment, et cela est encore plus vrai pour les &laquo;&nbsp;chapitres&nbsp;&raquo; à venir. Mais bon&#8230; Au-delà de la frustration de ne pas connaître un peu plus en détail l&#8217;implémentation de ces standards de la haute-disponibilité / scalabilité, cela fait toujours une bonne révision, intéressante, de ce qu&#8217;il y a à prendre en compte dans la mise à disposition d&#8217;un tel système de stockage. Allez&#8230; Fini ces digressions, continuons !</p>
<p>Le &laquo;&nbsp;niveau&nbsp;&raquo; de redondance, cité plus haut et permettant d&#8217;augmenter la taille du pool d&#8217;objets disponibles, rentre également dans cette optique de réessai. S3 permet ainsi d&#8217;éviter une inaccessibilité temporaire en augmentant le nombre d&#8217;objets disponibles afin de servir le maximum de requêtes concurrentes.</p>
<p><strong><em>Chapitre III : Surge Protection / Protection contre les (D)DOS</em></strong><br />
Et oui ! Un service exposé sur le net est donc potentiellement livré en pâture à de terribles botnet, une armée de zombies prêts à déferler sur votre pauvre service&#8230; Mais là aussi des parades sont possibles.</p>
<p>Il y a le &laquo;&nbsp;rate limiting&nbsp;&raquo;, où sur un &laquo;&nbsp;sur-accès&nbsp;&raquo; au service à partir d&#8217;IPs qui semblent être fautives, seule une partie des requêtes de ces machines seront traitées. De même que pour le réessai, il y a ce que l&#8217;on appelle &laquo;&nbsp;l&#8217;exponential back-off&nbsp;&raquo;, où les temps de réponse sont de plus en plus espacés afin de laisser le système respirer. Finalement, le &laquo;&nbsp;Cache TTL&nbsp;&raquo; (Time To Live) de chaque objet est augmenté avant son rafraichissement.</p>
<p>Un déni de service est bien sûr distingué d&#8217;une utilisation intensive de la ou des ressources, sachant que la cible n&#8217;est pas un pool d&#8217;objets défini mais bien le service dans son intégralité (saturation de la bande passante, &#8230;).</p>
<p>De même que précédemment, pour le détail des algorithmes&#8230; ;ob</p>
<p><strong><em>Chapitre IV : Eventual Consistency / Consistance éventuelle (des données)</em></strong><br />
La consistance éventuelle revient sur la problématique de la redondance (Chapitre I). En effet, le service S3 se doit d&#8217;assurer la sauvegarde des données par redondance, leur accessibilité à tout instant et&#8230; Leur consistance. C&#8217;est-à-dire que du fait de la redondance, il faut bien propager les modifications effectuées sur un objet donné à ces réplicats. Cela amène la question, &laquo;&nbsp;est-ce qu&#8217;un système peut à la fois être redondant (donc durable), disponible (donc accessible) et consistant (donc intègre &#8211; tous les réplicats d&#8217;un même objet sont identiques) à un instant donné ?&nbsp;&raquo;. La réponse est&#8230; presque. C&#8217;est pour cela que l&#8217;on parle de consistence éventuelle, la même notion que l&#8217;on retrouve dans les concepts de SimpleDB. Ces 3 éléments font obligatoirement l&#8217;objet d&#8217;un compromis et ne peuvent être assurés entièrement ensemble à un instant &laquo;&nbsp;t&nbsp;&raquo;. Par exemple, si on veux assurer la durabilité (donc redondance) et la consistance, il faut à un instant &laquo;&nbsp;t&nbsp;&raquo; rendre le service non accessible afin de propager les modifications&#8230; On peut retourner le problème dans tous les sens, on ne peut tout avoir à un instant &laquo;&nbsp;t&nbsp;&raquo;. Cela se traduit par le fait que sur un accès quasi simultané à un objet, un &laquo;&nbsp;PUT&nbsp;&raquo; suivi d&#8217;un &laquo;&nbsp;GET&nbsp;&raquo; par exemple, il se peut que l&#8217;on récupère l&#8217;ancienne version de l&#8217;objet sur le &laquo;&nbsp;GET&nbsp;&raquo;, parce que la propagation n&#8217;est pas (encore) effective. Ce fonctionnement est normal. Pensez à vos problématiques de réplications sur bases de données dans le cas où vous auriez des accès en continu très rapprochés !</p>
<p>C&#8217;est la notion de consistance éventuelle.</p>
<p>Vous pourrez retrouver un article <a title="Eventually Consistent - Revisited" href="http://www.allthingsdistributed.com/2008/12/eventually_consistent.html">Eventually Consistent &#8211; Revisited</a> sur le sujet sur <a title="All Things Distributed, Werner Vogels' weblog on building scalable and robust distributed systems" href="http://www.allthingsdistributed.com/">All Things Distributed</a>, Werner Vogels&#8217; weblog on building scalable and robust distributed systems.</p>
<blockquote><p>Eventually Consistent &#8211; Building reliable distributed systems at a worldwide scale demands trade-offs between consistency and availability.</p></blockquote>
<p><strong><em>Chapitre V : Routine Failure / Processus en cas de panne</em></strong><br />
Comme disait justement Simone lors de la présentation : &laquo;&nbsp;Viagra ? Cialis ? It will fail anyway !&nbsp;&raquo;. C&#8217;est la routine ! Enfin bon&#8230; Je parle pour la défaillance des composants hardware tout du moins ! :ob Disques, serveurs, datacenters, &#8230; Tout composants harware doit arriver un jour ou l&#8217;autre à terme (et oui !), alors&#8230; &laquo;&nbsp;just unplug it !&nbsp;&raquo;. Puisque tout est redondé et en haute disponibilité, pas de problème.</p>
<p>Pour plus d&#8217;informations sur la fin de vie du matériel chez Amazon et plus généralement sur la sécurité des services et la sécurité / confidentialité des données, vous pouvez consulter leur Livre Blanc sur le sujet sur leur site dans la rubrique <a title="Site de Amazon Web Services, Rubrique Sécurité" href="http://aws.amazon.com/security/">Sécurité</a> et le <a title="Site de Amazon Web Services, Rubrique Sécurité, Livre Blanc" href="http://awsmedia.s3.amazonaws.com/pdf/AWS_Security_Whitepaper.pdf">télécharger</a> (format PDF).</p>
<p><strong><em>Chapitre VI : Diversity / Diversité</em></strong><br />
&laquo;&nbsp;Diversifier pour mieux règner&nbsp;&raquo; pourrait-on dire. Et ce à 3 niveaux : Software, Hardware, Workload.</p>
<p>Pour éviter une panne généralisée du fait d&#8217;un composant matériel d&#8217;un fournisseur, un panel de composants physiques a été sélectionné à chaque niveau de l&#8217;infrastructure afin de s&#8217;assurer que si un des éléments est défaillant (mauvaise série, &#8230;), l&#8217;ensemble des composants entrant dans le cadre de la haute disponibilité ne tombent pas en panne en même temps.</p>
<p>Le principe est le même pour le software, pour le type et la version de l&#8217;OS des Hosts (les OS supportant les machines virtuelles) par exemple, pour les mêmes raisons (bugs, exploits, &#8230;).</p>
<p>Finalement la charge est elle aussi &laquo;&nbsp;diverse&nbsp;&raquo; en fonction des applications et des clients qui utilisent les services, permettant ainsi de lisser la charge et de ne pas saturer les services à certaines périodes.</p>
<p><strong><em>Chapitre VII : Integrity Checking / Vérification de l&#8217;intégrité (des données)</em></strong><br />
La corruption est partout ! En découle donc la vérification de l&#8217;intégrité&#8230; Et oui ! Encore une autre tâche nécessaire pour assurer un stockage de données de qualité. Mais il faut faire attention au coût et à la complexité engendrés par ces traitements. Le mode opératoire utilisé sur S3 est un checksum au niveau applicatif. Si une corruption de l&#8217;objet est détectée sur un checksum, il est alors remplacé par une version &laquo;&nbsp;correcte&nbsp;&raquo; à partir d&#8217;un de ces duplicats. De la même manière que précédemment, cette fonctionnalité est assurée en background et ne laisse rien transparaître à l&#8217;utilisateur.</p>
<p><strong><em>Chapitre VIII : Telemetry / Monitoring</em></strong><br />
Tout est dans le titre. Un monitoring est effectué sur le système afin de diagnostiquer son &laquo;&nbsp;état de santé&nbsp;&raquo;.</p>
<p><strong><em>Chapitre IX : Autopilot / Automatisation</em></strong><br />
Par ce que les processus humains sont faillibles et que le temps de réponse humain est lent, il est préférable d&#8217;automatiser (tiens ça me rapelle des choses ça Cf. <a title="Puppet et Capistrano : la clé de l’automatisation" href="http://decrypt.ysance.com/2009/07/automatisation-puppet-capistrano/">Puppet et Capistrano : la clé de l’automatisation</a>). Cela paraît évident dès que l&#8217;on a eu à monter et surtout à maintenir une infrastructure ! Alors au niveau d&#8217;un datacenter&#8230;</p>
<p><strong><em>Conclusion</em></strong><br />
Comme je vous l&#8217;ai dit dans l&#8217;article, ceux qui pensaient découvrir tous les secrets d&#8217;Amazon seront déçus. Pour des raisons évidentes de confidentialité et de sécurité, le détail et l&#8217;implémentation de chacun de ces principes n&#8217;est pas présenté. Je suis effectivement un peu frustré de ne pas en savoir plus, ne serait-ce que pour vérifier l&#8217;implémentation de tous les principes énoncés. Les constatations à notre niveau ne peuvent être qu&#8217;empiriques et, dans ce cadre, je suis entièrement satisfait du service, surtout quand on fait la relation entre le coût du service et sa qualité/fiabilité. Tous les mécanismes énoncés ne peuvent être mis en place qu&#8217;à une grande échelle, comme dans les datacenters d&#8217;Amazon, vu le coût en ingénieurie et matériel que cela engendre afin d&#8217;implémenter ces mécanismes (autant au niveau algorithmes/software qu&#8217;au niveau hardware).</p>
<p>De plus, les mêmes principes ont été apportés aux autres services (ou tout du moins des principes similaires fonction du service). Les Web Services Amazon sont fondés sur le même modèle et les mêmes règles de base. Cela nous laisse donc entrevoir une qualité de service, au niveau des différentes fonctionnalités que couvre le large scope Amazon, que nous ne pourrions nous offrir en interne ou chez certains de nos hébergeurs physiques.</p>
<p>Sorti de S3 (ou d&#8217;autres services Amazon), je trouve ces notions également intéressantes à prendre en compte dans nos infrastructures, à un moindre niveau bien sûr, car ces principes sont plein de bon sens et il est intéressant de se poser au moins les questions.</p>
<p>Vous pouvez également recevoir toutes les nouveautés sur AWS et autres sujets techniques (scalabilité, haute dispo, &#8230;) sur <a title="Twitter Frédéric FAURE" href="http://twitter.com/fredericfaure">Twitter @fredericfaure</a>.</p>
<p><strong><em>Frédéric FAURE</em></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://decrypt.ysance.com/2009/11/les-9-principes-de-s3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Load Balancing – Haute Dispo – Clustering. Un triptyque parfois confus…</title>
		<link>http://decrypt.ysance.com/2009/04/load-balancing-haute-dispo-clustering/</link>
		<comments>http://decrypt.ysance.com/2009/04/load-balancing-haute-dispo-clustering/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 16:49:46 +0000</pubDate>
		<dc:creator>Frédéric Faure</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Clustering]]></category>
		<category><![CDATA[Haute Disponibilité]]></category>
		<category><![CDATA[Load Balancing]]></category>

		<guid isPermaLink="false">http://godard.ysance.com/~decrypt/?p=97</guid>
		<description><![CDATA[Il m’arrive souvent chez les clients de rencontrer la même confusion autour de ce triptyque, ce qui peut mener à de sérieux problèmes, surtout quand le client se base sur l’idée que « dans le doute on prend toutes les options, c’est forcément mieux ! ». C’est faux !
Une explication de chacune de ces notions s’impose.

[...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="margin: 0cm 0cm 0pt;">
<div class="mceTemp"> </div>
<div class="mceTemp">Il m’arrive souvent chez les clients de rencontrer la même confusion autour de ce triptyque, ce qui peut mener à de sérieux problèmes, surtout quand le client se base sur l’idée que « dans le doute on prend toutes les options, c’est forcément mieux ! ». C’est faux !</div>
<p>Une explication de chacune de ces notions s’impose.</p>
<p><strong><em>Découpage et positionnement des fonctionnalités</em></strong></p>
<div><strong><em> </em></strong></div>
<div><strong><em> </em></strong></div>
<div><strong><em> </em></strong></div>
<div><strong><em> </em></strong></div>
<div id="attachment_118" class="wp-caption alignnone" style="width: 444px"><strong><em><img class="size-full wp-image-118" title="Architecture applicative standard" src="http://decrypt.ysance.com/wp-content/uploads/2009/04/architecture_app_std.png" alt="Architecture applicative standard" width="434" height="538" /></em></strong><p class="wp-caption-text">Architecture applicative standard</p></div>
<p><strong><br />
</strong></p>
<p><strong><em>Load Balancing ou répartition de charge<br />
</em></strong>Cette tâche est acquittée par le load balancer ou répartiteur de charge. Il s’agit du point d’entrée de l’architecture applicative (on peut trouver avant firewall, reverseproxy, …) et il permet de répartir les requêtes sur différentes « branches » identiques entre elles, donc la charge, entre les services répliqués. On peut définir l’algorithme de la répartition (roundrobin, stickysession, …), la pondération sur chaque backend (serveur récupérant les requêtes distribuées par le balancer), la politique de vérification de l’état des backends (nombre de requêtes en erreur, intervalle de vérification, …), … De nombreuses options sont disponibles de manière générale et en fonction des balancers en particulier.</p>
<p>Il est à noter que le balancer peut être hard ou soft. Je constate souvent que les clients préfèrent acheter un balancer hard, probablement pensant que c’est un gage de fiabilité et de performances. Effectivement le balancer hard dispose d’une infrastructure matérielle conçue spécialement pour cette tâche et permet donc des performances un peu meilleure. Il dispose également d’un paramétrage plus poussé (donc plus de possibilités, mais plus complexe à prendre en main). Cependant, dans quasiment tous les cas que j’ai rencontré, un balancer soft aurait amplement suffit, autant en termes de performances que d’options… Le balancer est un dispatcher (intelligent tout de même) et ne consomme donc pas (ou peu) de CPU, de mémoire, … Il n’est donc pas gourmand et fait juste la tâche pour laquelle il a été conçu. Le balancer soft que j’utilise en général est HAProxy, et pour l’instant je n’ai pas à m’en plaindre. Facile à configurer, il supporte une montée en charge importante comme un grand (cf. « Conception d’une infrastructure sur AWS : best practices ! ») ! Bien sûr, d’autres balancer soft (et gratuits bien entendu ^^) existent et chacun trouvera son bonheur, n’hésitez pas à installer et comparer.</p>
<p>Il est intéressant de mettre en place du balancing à partir du moment où la population cible d’utilisateurs n’est pas figée ou bien qu’elle ne peut être supportée par un seul serveur.</p>
<p>Il faut en revanche bien penser qu’à partir du moment ou l’architecture aura plusieurs branches identiques de services, le déploiement devra être effectué de manière iso et de préférence (si vous ne le faites pas c’est à vos risques et périls) automatisée sur les X backends.</p>
<p>Il faut également penser à minima en termes distribué et intégrer la notion du partage des sources de données, chaque branche de l’architecture devant avoir accès à une ou des sources de données centralisées et partagées : partage de fichiers, cache réseau, …</p>
<p>Cela a un coût supplémentaire en termes de machines, de mise en place d’un déploiement automatisé et de réflexion distribuée, mais le bénéfice est toujours là et la configuration relativement simple.</p>
<p><strong><em>Haute Dispo</em></strong><br />
La haute disponibilité s’appuie tout d’abord sur le load balancing. C’est le second niveau que l’on peut apporter à l’architecture. La haute dispo, pour être efficace, doit être mise en place à tous les niveaux de l’architecture, 2 formules étant disponibles : </p>
<p style="padding-left: 30px;">• Soit plusieurs services qui fonctionnent en parallèle et répondent aux différentes requêtes dispatchées, si l’un d’entre eux tombe, les autres sont à même de supporter la charge supplémentaire induite et de répondre convenablement. C’est ce que l’on trouve au niveau des serveurs HTTP ou applicatifs.</p>
<p style="padding-left: 30px;">• Soit une machine attend en backup, et si elle (ou un système externe) détecte (Heartbeat, …) la perte de la machine principale, elle prend le relai (IP failover, …). C’est ce que l’on trouve au niveau du balancer ou de la base.</p>
<p>Au niveau de la base, le fonctionnement est un peu plus complexe, car contrairement au balancer qui n’héberge pas de données applicatives, la base doit assurer la mise à disposition des données à la « date du crash – n » avec « n » le plus petit possible. Les données sont donc répliquées sur le backup en quasi temps réel. Il est aussi possible d’utiliser la base de backup (ou slave) en lecture afin de diminuer la charge sur la base principale (master). La base est donc un sujet plus complexe.</p>
<p>Concernant les services fonctionnant en parallèle, il est important qu’à chaque niveau, la requête puisse être redirigée sur un autre service équivalent en cas de défaillance. Le balancer n’ayant pas la même visibilité que le serveur HTTP sur la disponibilité du serveur applicatif, le serveur HTTP doit donc faire du dispatching passif. Dans le cas où il n’y a pas de serveur applicatif, parce que le site est en PHP par exemple, la mise en place est d’autant plus simple : pas besoin de dispatching à ce niveau et de questions métaphysiques… Mais ce cas est bien moins amusant ! ^^</p>
<p>Dans le cas d’une architecture avec serveurs applicatifs, il convient de répondre à un certain nombre de questions/remarques que l’on m’a posées plus d’une fois, en particulier sur le dispatching au niveau du serveur HTTP et son utilité :</p>
<p style="padding-left: 30px;"><strong><em>« Le serveur web est-il capable de détecter une défaillance du serveur applicatif ? »<br />
</em></strong>Oui. Si le serveur http dispose d’un module de dispatching, comme Apache par exemple, il est plus que probable qu’il soit capable de détecter la défaillance de son backend (le serveur applicatif) et de rediriger les requêtes sur les autres (fonction du paramétrage retenu sur le nombre d’essais et le délai avant déclaration du backend HS). J’ai surtout travaillé avec Apache, mais pense que c’est la base de tout fonctionnement de serveur web… Peut-être y a-t-il un exemple pour me faire mentir ? Il est à noter tout de même que Apache peut détecter le statut du serveur applicatif, mais pas de la ou des applications ! Si l’application provoque des erreurs internes sur le serveur applicatif ou ne renvoie pas les réponses escomptées, cela rentre dans le cadre d’un monitoring de l’application (fonctionnel et technique) via une interface et des outils spécifiques.</p>
<p style="padding-left: 30px;"><strong><em>« Alors pourquoi ne pas mettre un Apache (en l’occurrence) en balancer ? »<br />
</em></strong>Parce que ce n’est pas son rôle premier et il n’a pas toutes les fonctionnalités d’un HAProxy, par exemple, et surtout parce qu’il effectue un certain nombre de traitements liés à sa fonctionnalité de serveur web qui n’ont rien à faire sur un répartiteur de charge dont le fonctionnement doit être minimaliste afin d’encaisser toute la montée en charge en un point.</p>
<p style="padding-left: 30px;"><strong><em>« Mais en activant le dispatching Apache, il est difficile de suivre les log d’une transaction pour un utilisateur donné au niveau du serveur applicatif »<br />
</em></strong>C’est là qu’intervient le « sticky session ». Si le site se limite à des serveurs web, pour un site PHP par exemple, le « sticky session » doit être positionné au niveau du HAProxy. Dans le cas d’un site utilisant des serveurs applicatifs, le « sticky session » doit être positionné au niveau des serveurs Web. En effet, le « sticky session » doit être positionné un cran avant la brique gérant la session. Le « sticky session » est tout simplement un flag positionné dans un cookie (de session par exemple) et qui permet pour un utilisateur donné de savoir sur quel serveur il a été redirigé lors de ses requêtes précédentes et donc de pouvoir le rediriger à nouveau dessus afin qu’il récupère sa session. Si « son » serveur est HS, il est alors redirigé vers un autre et sa session recréée, à vide (c’est là qu’intervient le clustering, mais on verra ça plus tard ^^).</p>
<p style="padding-left: 30px;"><strong><em>« Faire de la répartition de charge au niveau du serveur Apache n’annule-t-elle pas celle du balancer ? »<br />
</em></strong>De manière générale : Non. En général, car il faut prendre en compte les différents algorithmes de répartition, mais vu qu’en général c’est du roundrobin… Y’a pas de souci. Je parle au niveau de Apache de dispatching passif. Si on effectue une répartition par requête sans pondération au niveau de Apache, cela n’annule en rien la répartition de charge du balancer (même si il y avait de la pondération au niveau du balancer). Tout simplement la charge est répartie au niveau des Apache, qui eux même dispatchent les requêtes qu’ils reçoivent équitablement au niveau des serveurs applicatifs.</p>
<p style="padding-left: 30px;"><strong><em>« Et si on veut quand même conserver un lien « un pour un » entre Apache et le serveur applicatif ? »<br />
</em></strong>Et bien optez au niveau du Apache pour du « hot standby ». En fait, tant que le ou les serveurs du pool défini répondent, les requêtes sont redirigé vers lui ou eux, et si plus aucun ne répond, dans notre cas si le serveur ne répond plus, alors on passe sur le serveur de backup (« hot standby ») qui peut être l’un des autres serveurs applicatifs. Dès que le serveur principal ou un des serveurs principaux revient, il récupère de suite le trafic.</p>
<p>La haute disponibilité s’appuie donc sur le load balancing et est déjà un peu plus complexe à mettre en place. Il faut bien penser à redonder chaque élément de l’architecture avec des services en parallèle ou des backup. Si vous voulez vraiment de la haute disponibilité, pensez également à brancher les serveurs sur des alimentations électriques séparées (ne riez pas, c’est du vécu…) et à prendre en compte votre réseau électrique de manière générale. Il y a plusieurs niveaux de haute disponibilité et c’est à chacun de définir son compromis.</p>
<p>De même que pour le balancing, la haute disponibilité ne fera pas de mal à l’architecture. C’est « juste » plus coûteux en termes de réflexion, de configuration et de ressources.</p>
<p><strong><em>Clustering</em></strong><br />
Le clustering est le dernier niveau de la haute disponibilité. C’est à ce niveau qu’il faut surtout réfléchir à la notion de compromis ! En effet, le clustering est coûteux à différents niveaux et risqué si mal maîtrisé.</p>
<p>Il faut aussi faire attention au terme cluster qui regroupe des notions variées et est employé de manière générale pour un regroupement de machines, quelques soient leurs inter dépendances. Dans notre cas, nous parlerons de clustering pour la réplication de sessions au niveau des serveurs applicatifs.</p>
<p>Tout d’abord le clustering se met en place afin de pouvoir répliquer les informations de sessions, donc volatiles, afin que n’importe quel serveur puisse reconstruire la session de l’utilisateur. Il est utilisé pour des sites ne pouvant tolérer de rupture de service dans les « occasions » suivantes :</p>
<p style="padding-left: 30px;">• si une des machines utilisant les sessions crashe, afin de reconstruire la dite session sur une autre machine,</p>
<p style="padding-left: 30px;">• afin de pouvoir effectuer des maintenances ou des mises à jour de version de l’application sans rupture de service.</p>
<p>J’ai vu pas mal de clients très embêtés par leur clustering parce que leur application était lente, parce que ça consommait des ressources effrayantes, … parce que leurs serveurs applicatifs ne démarraient même plus à cause de la surcharge de trafic généré (ne riez toujours pas, c’est du vécu…) !!!</p>
<p>En effet, le clustering est basé sur la réplication des informations de sessions entre les différents serveurs applicatifs et s’effectue en multicast, c&#8217;est-à-dire qu’à chaque modification des informations de la session d’un utilisateur, le serveur applicatif l’annonce sur le réseau à destination des autres serveurs écoutant sur l’adresse de multicast. Le paramétrage des nœuds du cluster, du ttl (time to live) des trames, l’étanchéité des sous-réseau, … doivent être impeccables, sous peine d’avoir de terribles latences. De plus, il faut garder un œil vigilent sur les développements applicatifs afin de limiter de façon drastique les informations qui auront leur place en session.</p>
<p>Il ne faut pas partir en se disant « on réplique les sessions, de toute façon ça ne fera pas de mal… Qui peut le plus, peut le moins…» ! Si c’est mal configuré, et c’est souvent le cas, le résultat est médiocre et au final après moult temps et argent gâchés, la fonctionnalité est retirée. Il faut l’utiliser à bon escient, et si le besoin est réel, la mettre en place rigoureusement après s’être correctement documenté…</p>
<p>De plus, la fonctionnalité peut bien souvent être contournée, par exemple pour un site marchand, j’ai déjà entendu : « si notre client perd son caddie, c’est critique ! ». Le besoin est tout d’abord à relativiser car le cas où un serveur applicatif est HS est (et doit être) un évènement rare (sauf courte période de maintenance la nuit par exemple). De plus, pourquoi ne pas stocker ses informations en base de données ou dans une source de données centralisée (cache réseau, …) afin de pouvoir gérer ce genre de données et y accéder ailleurs si besoin.</p>
<p>Concernant les mises à niveau logicielles, il est préférable, à mon avis, d’accepter une rupture de service de quelques minutes via une méthodologie et un scripting rigoureux et d’avoir un site efficace le reste du temps, qu’un site qui fonctionne en permanence mais avec un temps de réponse moyen, voire pire…</p>
<p><strong><em>Conclusion</em></strong><br />
Je n’ai fait que brosser le sujet qui demande réflexion quand on rentre dans les détails. Il y a beaucoup de notions à connaître que l’on acquiert avec l’expérience. Mais les grandes lignes sont là.</p>
<p>Comme dans tout projet, il faut d’abord définir ses besoins et à partir de là, envisager les solutions à mettre en place et en accepter les compromis. Ce n’est pas parce que vous ne mettrez pas de répartition de charge, de haute dispo ou de clustering que votre architecture et au final votre application ne fonctionneront pas ou encore pire… seront « has been » (oui ça c’est terrible, c’est mal les vieux concepts… Pourtant ça marche souvent très bien et c’est même efficace parfois…) ! Vous avez juste un serveur HTTP et un serveur applicatif parce que votre charge est modérée et avez prévu un PRA (Plan de Reprise d’Activité) rigoureux et efficace via scripting ! Bingo ! Vous aurez un downtime de 5-10 minutes en cas de problème, mais à côté de ça votre application répond bien pour un coût d’infra minimaliste.</p>
<p>Il faut juste adapter les possibilités architecturelles à vos besoins et ne pas créer de dépenses inutiles. La compréhension de chaque option à disposition est la clé de vos choix.</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><em><strong>Frédéric FAURE</strong></em></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"> </p>
]]></content:encoded>
			<wfw:commentRss>http://decrypt.ysance.com/2009/04/load-balancing-haute-dispo-clustering/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

