<?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; Sharding / Partitionnement</title>
	<atom:link href="http://decrypt.ysance.com/category/architecture/sharding/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>Scaling an AWS infrastructure 2/2 : the pattern</title>
		<link>http://decrypt.ysance.com/2010/08/scaling-an-aws-infrastructure-2-the-pattern/</link>
		<comments>http://decrypt.ysance.com/2010/08/scaling-an-aws-infrastructure-2-the-pattern/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 16:43:48 +0000</pubDate>
		<dc:creator>Frédéric Faure</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Sharding / Partitionnement]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[Casual Gaming]]></category>
		<category><![CDATA[LVM]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RAID]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Tokyo Cabinet]]></category>
		<category><![CDATA[Tokyo Tyrant]]></category>

		<guid isPermaLink="false">http://decrypt.ysance.com/?p=1525</guid>
		<description><![CDATA[<img class="size-medium wp-image-1411 alignleft" title="Scale-Out in the Matrix" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/MatrixScaleOut-300x123.png" alt="Scale-Out in the Matrix" width="204" height="82" />

How do you scale an <a title="Site de Amazon Web  Services" href="http://aws.amazon.com/">AWS</a> (Amazon Web Services) infrastructure? In Part Two of the article, I describe the architecture model and the underlying technical components you should use in order to implement a scalable infrastructure. We will look in particular at the optimisation of data access in scale-out-type architectures suitable for implementation as a distributed system, as much at the data model level as the lower layers for I/O optimisation. We will also examine the recommended development concepts such as Stateless, in the finest REST tradition. I will end the article with some tips and tricks. My aim is to help you set up and optimise your infrastructure by understanding how Amazon tools operate and to get the most benefit from them.

[...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-medium wp-image-1411 alignleft" title="Scale-Out in the Matrix" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/MatrixScaleOut-300x123.png" alt="Scale-Out in the Matrix" width="204" height="82" /></p>
<p>How do you scale an <a title="Site de Amazon Web  Services" href="http://aws.amazon.com/">AWS</a> (Amazon Web Services) infrastructure? In Part Two of the article, I describe the architecture model and the underlying technical components you should use in order to implement a scalable infrastructure. We will look in particular at the optimisation of data access in scale-out-type architectures suitable for implementation as a distributed system, as much at the data model level as the lower layers for I/O optimisation. We will also examine the recommended development concepts such as Stateless, in the finest REST tradition. I will end the article with some tips and tricks. My aim is to help you set up and optimise your infrastructure by understanding how Amazon tools operate and to get the most benefit from them.</p>
<p><em><strong>Scale-out</strong></em><br />
<img class="size-full wp-image-1424 alignright" title="Scale-Up in Ghost Buster" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/GhostBusterScaleUp.jpg" alt="Scale-Up in Ghost Buster" width="116" height="170" />Scale-out is the opposite of scale-up: the latter means the dynamic expansion on the fly of a given server’s resources (addition of RAM or CPU). Thus, the application continues running on a single machine whose capacity has been increased. Scale-out (the AWS way), on the other hand, offers to increase the number of servers in order to respond to the increased load of an application. Ultimately, the global potential of the infrastructure increases too, but is divided among several servers. This implies that the application supported on the server had been thought out in terms of distribution, that is, it can be executed in parallel on several servers without the risk of corrupting the business logic (think to shared session management or no session, for example) or creating a problem of access to the resources (which must then be available via the network and not locally on any given server, for example).</p>
<p>Scale-out can be likened to Agent Smith in <em>Matrix</em>. As for scale-up, think more along the lines of the Stay Puft Marshmallow Man in <em>Ghostbusters</em>!</p>
<p><strong><em>Stateless</em></strong><br />
The best way to obtain an application that is both easy to distribute and high performing, is to plan for it in stateless mode. This means that it’s the client request which must contain all the information enabling the request to be processed by the server, either via a cookie, or else via the URL parameters. Whenever possible you should choose this approach at any price, compared to the stateful mode in which the server must keep a context for each client to be able to respond to the request. The stateless concept is one of the great REST concepts. While we’re on the subject, I strongly recommend you read this <a title="REST, un style d'architecture universel" href="http://www.figer.com/publications/REST.htm">excellent article on REST</a> (in French) by Jean-Paul Figer to appreciate the style in all its simplicity and power.</p>
<p>If you have to manage stateful, you will need to use a network cache such as <a title="Site de Memcached" href="http://memcached.org/">Memcached</a>, to share the contexts among your different servers. Don’t even consider the local cache and sticky session package, as you will have trouble getting even distribution of the load balancing. It’s not a good idea to use a cluster which communicates in multicast either, because the Amazon network does not allow that … Or all the servers could communicate in unicast with a gateway which takes care of redistributing the communications… Are you sure you don’t prefer stateless? ;ob</p>
<p>The implementation of stateless applications did not arrive with Cloud Computing and AWS: on the other hand, if you don’t think along these lines, you won’t be able to make the most of all the energy and flexibility they provide.</p>
<p><strong><em>Optimisation of data</em></strong> <strong><em>access</em></strong><br />
Optimising data access requires two elements:</p>
<ul>
<li>The data model and software architecture that are found in scalable architecture, whether you are on an AWS infrastructure or not.</li>
<li>I/O management, which can be optimised in particular by thoroughly exploiting AWS.</li>
</ul>
<p><em><span style="text-decoration: underline;">The scalable model </span></em><br />
This subject deserves an entire article of its own, but the scalable model is in keeping with a rather classic model within the casual gaming-type applications, or more generally linked to applications based on the social graphs, or centred on a distinct business concept in particular.</p>
<p>To summarize, two methods of data storage are:</p>
<ul>
<li>Storage of what we’ll call the meta-model, which is not intended for distribution, built on a structured, indexed relational base (even though essentially used in the form of a key-value access), containing the general information of each user (in the case of a social application the following: <em>name</em>, <em>top score</em>, <em>previous day’s wins</em>, etc.), primarily accessed in read and for which it is possible to alleviate the load via a Memcached in front of it. You can therefore carry out SQL-type set-based requests (ensemblist) and thus recover information by using clauses (<em>WHERE</em>). This base can be a MySQL or a PgSQL for example. I suggest you read this <a title="Dotdeb, MySQL et Amazon : RDS vs EC2" href="http://www.dotdeb.org/2010/05/04/mysql-on-amazon-benchmarks-rds-vs-ec2/">very interesting report</a> by Guillaume Plessis, comparing MySQL installed on an <a title="Site de Amazon Web Services, Rubrique EC2" href="http://aws.amazon.com/ec2/">EC2</a> with the Amazon <a title="Site de Amazon Web Services, Rubrique RDS" href="http://aws.amazon.com/rds/">RDS</a> (Relational Database Service). I don’t risk ruining the suspense by telling you that databases are a real bearded geek affair! :o)</li>
<li>Storage for more volatile data (such as game data etc.), with a heavy write:read ratio, difficult to cache, and for which you must choose a real, structured, non-relational storage solution of a key-value-type (NoSQL / Not only SQL, some would say), thus enabling easy distribution of the data on X servers. I can mention a few names: <a title="Site de Redis" href="http://code.google.com/p/redis/">Redis</a>, <a title="Site de  Tokyo Tyrant" href="http://1978th.net/tokyotyrant/">Tokyo Tyrant</a>/<a title="Site de Tokyo Cabinet" href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a>, <a title="Site de MemcacheDB" href="http://memcachedb.org/">MemcacheDB</a>.  And also the new peer to peer models such as <a title="Site de Cassandra" href="http://cassandra.apache.org/">Cassandra</a>.</li>
</ul>
<div id="attachment_1353" class="wp-caption alignright" style="width: 291px"><img class="size-full wp-image-1353" title="Tokyo Cabinet" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/TokyoCabinet.png" alt="Tokyo Cabinet" width="281" height="183" /><p class="wp-caption-text">Tokyo Cabinet</p></div>
<p>In this case, Tokyo Tyrant / Tokyo Cabinet is a solution that I have implemented, which I find satisfactory (note that a new tool <a title="Site de Kyoto Cabinet" href="http://1978th.net/kyotocabinet/">Kyoto Cabinet</a> has come and one of his worthy features is to optimize the management of multi threading and thread concurrency compared to Tokyo Cabinet). Tokyo Tyrant / Tokyo Cabinet is a twosome, managing the requests from distant servers (network interface) and access to the storage system respectively. Six APIs are available for storing the data:</p>
<ol>
<li>On memory Hash,</li>
<li>On memory B+tree,</li>
<li>File Hash,</li>
<li>File B+tree,</li>
<li>Fixed-length Array,</li>
<li>Table.</li>
</ol>
<p>Each of them has its own characteristics and responds to particular requirements in terms of performance and practicality.</p>
<p>Regarding performance: apart from its natural capabilities, it has the notable advantage of not managing authentication (which is usual in key-value storage systems &#8211; there are exceptions like <a title="Site de Amazon Web Services, Rubrique SimpleDB" href="http://aws.amazon.com/simpledb/">SimpleDB</a>, for example &#8211; ; security is supposed to be guaranteed at the network level for accessing the storage system and at the applications level for access to data – so that you can only retrieve that which concerns you). This reduces the access rate (no need for authentication requests) compared to a classic database. Furthermore, no reconstruction of onerous index management is required (possible however on the Tokyo Team’s API ‘Table’) … It goes without saying that what’s really time-consuming about data access via the network (between the web or application server and Tokyo Tyrant) is… the network! So in all cases, at the client (API) level you should use ‘mget’ (multi get), for example, by positioning a array of keys that you wish to recover in the parameters rather than performing a ‘get’ N times from the client, therefore creating N network accesses. ‘mget’ will be resolved at the Tokyo Tyrant level.</p>
<p>The arguments concerning this tool should be applied to all key-value-type storage.</p>
<p><em><span style="text-decoration: underline;">I/O management</span></em><br />
Now we come to the specific characteristics of AWS in terms of storage: <a title="Site de Amazon Web Services, Rubrique EBS" href="http://aws.amazon.com/ebs/">EBS</a> (Elastic Block Stores). EBS volumes are network disks optimised for I/Os, easy to use, ensuring the survival of crucial data during an EC2 (volatile) shutdown. On a purely practical note, I did however notice latency variances: not enormous, but on an application that is much in demand, it does get noticed. This is not insurmountable, it’s simply something to bear in mind. If your servers’ Load Average increases, it’s not necessarily the CPU which is to blame … Think I/Os! ;ob</p>
<p>Firstly think striping, therefore RAID0. No need for mirroring (RAID1), as the data safety in EBS is already guaranteed by Amazon, transparently, by network replication: let’s make the most of this service and concentrate on striping. Remember too to spread the writes of the different physical files (data, update logs, etc.) among different disks (for tools using update logs &#8211; and this is the case for MySQL and Tokyo Tyrant for example &#8211; do remember to set their capacity parameters). This is what allows you the best optimisations. Next, choose your filesystem carefully with regard to the tool (EXT3, XFS, etc.) and consider the mounting options (noatime, nodiratime, etc.) Finally, check the default scheduler on the EC2 instances that you are starting up: it’s the NOOP scheduler by default (I/O requests in a simple FIFO file). Consider something more efficient, such as CFQ (Completely Fair Queuing). Well, I say that, but it always depends on the top software layer, and if and how it manages the priorities: <a title="MySQL Performance Blog, Linux  schedulers in tpcc like benchmark" href="http://www.mysqlperformanceblog.com/2009/01/30/linux-schedulers-in-tpcc-like-benchmark/">in this example</a> (which is not on EBS) on the MySQL Performance Blog, it appears that the NOOP and DEADLINE schedulers are the best for improving the InnoDB I/O. It just goes to show, it’s always better to test first for your own particular case! ;ob</p>
<div id="attachment_1177" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-1177" title="Logical Volume Management" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/Archi_LVM-300x280.png" alt="Logical Volume Management" width="300" height="280" /><p class="wp-caption-text">Logical Volume Management</p></div>
<p>Another tool I have used with the EBS and which works very well is LVM2 (Logical Volume Management, version 2). I haven’t used it with an architecture with a high number of IOPS (I/O Operations Per Second) and have therefore not tested the striping possibilities (RAID0) offered by the tool. On the other hand, I have used it with an infrastructure which had to be able to tolerate considerable increases in data volume but without interruptions in service. The snapshot and volume re-creation operations of an EBS are too long. LVM provides the solution, because this abstraction layer enables the management of software volumes independent of physical resources: you only need to raise a new EBS resource (a command line), associate it with the EC2 instance (another command line) and add this resource to the LVM resource pool. All that’s needed is to increase the logical volume (still transparent, without service interruption), then extend the file system. That last operation (which is a joint operation with the re-creation of the EBS volume) can necessitate shutting down the service for a few moments (around ten seconds). Note that it is possible to hot-extend your file system with EXT3, personally, I prefer a service interruption of a few seconds on this type of very short but crucial operation. ;ob  And what’s more, it is easy to perform backups on an LVM system offering a snapshot differential option, which you can mount like an independent logical volume: when there is a modification to the origin volume, the initial value is copied in the snapshot volume, so you can snapshot large volumes on a limited space because only the frequency of modification is what counts. You can find further information on LVM2 and EBS by consulting this <a title="Decrypt,  EBS et LVM2 ou comment optimiser l’élasticité des AWS" href="../2010/06/ebs-et-lvm2-ou-comment-optimiser-elasticite-des-aws/">very good article</a> (in French) by Laurent Roux.</p>
<p>All these examples demonstrate that EBS are a very useful resource: you have to consider them firstly as a means of ensuring the durability of important resources before taking into account the performance aspect. In fact, performance is not necessarily better on an EBS than on the local disks of an EC2 instance (Cf. <a title="Ma petite présentation au Amazon web service french user group  2010" href="http://www.karlesnine.com/post/2010/05/07/Amazon-web-service-french-user-group-2010">a simple and interesting test</a> (in French) by Charles-Christian Croix. Or, to see some slightly more complex tests, Google <em>“performance ephemeral disk ebs volume raid”</em>. There are quite a few very interesting cases, and I must confess I find it hard to choose between them ;ob). Nevertheless, when you are committed to ensuring the safety of your data and thus using EBS (which, for those in the know, is comparable to a LUN on a SAN), there are several ways of maximising their performance.</p>
<p>It should be noted that, for a pure performance solution, use them to spread the files (and thus the I/Os) among several EBS disks.</p>
<p>Note however that the EC2 bandwidth is inevitably limiting, once you reach a certain threshold: adding EBS is helpful for smoothing out the variance differentials (in RAID0) or for optimising the throughput, but the fact remains that if you add several EBS to your EC2 instance and they are in great demand… it&#8217;s the EC2 bandwidth that jams. You will have to add a new EC2 (scale-out to increase the resources &#8211; in this case the bandwidth), attach new EBS to it (don’t forget that an EBS may be attached only to a single EC2 at a time) and partition the data onto it (sharding).</p>
<p>In all cases, handling the EBS is easy and this flexibility is a plus.</p>
<p><strong><em>Tips &amp; tricks</em></strong><br />
This last section contains some useful hints.</p>
<p><em><span style="text-decoration: underline;">Aliases &amp; IPs</span></em><br />
Remember, on an AWS infrastructure, to position aliases corresponding to your instances’ private IPs in the ‘hosts’ file, which you then deploy via <a title="Site de Puppet" href="http://www.puppetlabs.com/">Puppet</a> for greater reactivity, given that the IPs are ‘variable’ (when you shut down one instance and start up another straight away, you will not keep the same IP). By using the the ‘hosts’ file you will avoid provoking internal DNS resolutions for Amazon.</p>
<p><em><span style="text-decoration: underline;">CDN &amp; S3 Headers</span></em><br />
For the CDNs (Content Delivery Networks) that you will have to use in a scalable architecture, remember to use S3 in order to provide images and other static content. It’s useless to keep a Web server only for that purpose: that’s what S3 is for, and at minimal cost.</p>
<p>Remember also that in certain cases where your traffic is more moderate and you don’t wish to change over to a CDN (for reasons of cost, for example ;ob), you can always optimise the management of your resources on S3 by using the metadata attributed to the said resources on S3, by positioning, for example, <em>Cache-Control</em> or <em>Expires-</em><em>type</em> headers. You may visualise the metadata via the new <a title="Site de Amazon Web Services, Console AWS, Onglet S3" href="https://console.aws.amazon.com/s3/home">S3 tab</a> of the Amazon management console.</p>
<p><em><span style="text-decoration: underline;">Backups… What else?</span></em><br />
S3 is also the solution for backups. I have not found any integrated tools satisfactory for this task: I simply use a command line tool “<a title="Site de s3tools, s3cmd" href="http://s3tools.org/s3cmd">s3cmd</a>” in order to store my backups. I integrated this tool into <a title="Site de Capistrano" href="http://www.capify.org/">Capistrano</a> tasks called by cron. s3cmd is very simple to operate, enables the use of S3 services and offers the possibility of transferring data in HTTPS, and also to store it in encrypted format.</p>
<p><strong><em>Conclusion</em></strong><br />
There are many more things to be said on this subject, but the abovementioned points are, in my opinion, the essential ones, in any case with regard to using the services provided by AWS. To sum up:</p>
<ul>
<li>Stateless and REST are, generally      speaking, better adapted to AWS, since they enable easy sharing of the load on an infrastructure which      can adapt to the increased load on a scale-out model.</li>
<li>Data access always creates a bottleneck in      distributed scaling applications. At this level it’s a matter of      working on the data model and making good use of the adequate storage      systems:
<ul>
<li>SQL technologies for metadata able to       necessitate set-based querying (ensemblist) and relational things, while making maximum use of a       network cache for information with a high read:write ratio.</li>
<li>NoSQL / Not only SQL / key-value       technologies for information which can be accessed with a single key, and       thereby benefit from the distribution inherent in scale-out.</li>
</ul>
</li>
<li>Finally, remember the lower layers by      selecting an appropriate filesystem and scheduler. You should also      consider RAID (striping) and LVM (volume extension and snapshot      differential) to get the most out of the EBS’ versatility and allocation      of the I/Os on different devices (always being careful with your EC2      bandwidth, which can become restrictive: in that case add one or more EC2      instances to gain bandwidth and partition – shard – the data on new EBS).</li>
</ul>
<p>I hope you enjoyed this second part of my report on the scalability of AWS infrastructures.</p>
<p><em><strong>Frédéric FAURE</strong></em> <a title="Frédéric FAURE @Twitter" href="http://twitter.com/fredericfaure">@Twitter</a> <a title="Ysance, Simplifions les projets informatiques" href="http://www.ysance.com/">@Ysance</a></p>
]]></content:encoded>
			<wfw:commentRss>http://decrypt.ysance.com/2010/08/scaling-an-aws-infrastructure-2-the-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scaler une infrastructure AWS 2/2 : le modèle</title>
		<link>http://decrypt.ysance.com/2010/07/scaler-une-infrastructure-aws-2-le-modele/</link>
		<comments>http://decrypt.ysance.com/2010/07/scaler-une-infrastructure-aws-2-le-modele/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 14:41:53 +0000</pubDate>
		<dc:creator>Frédéric Faure</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Sharding / Partitionnement]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[Casual Gaming]]></category>
		<category><![CDATA[LVM]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RAID]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Tokyo Cabinet]]></category>
		<category><![CDATA[Tokyo Tyrant]]></category>

		<guid isPermaLink="false">http://decrypt.ysance.com/?p=1304</guid>
		<description><![CDATA[<img class="size-medium wp-image-1411 alignleft" title="Scale-Out in the Matrix" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/MatrixScaleOut-300x123.png" alt="Scale-Out in the Matrix" width="204" height="82" />

Comment scaler une infrastructure <a title="Site de Amazon Web Services" href="http://aws.amazon.com/">AWS</a> (Amazon Web Services) ? Je vais décrire dans cette deuxième partie de l'article le modèle de l'architecture et les composants techniques sous-jacents à adopter afin de mettre en place une infrastructure scalable. Nous aborderons tout particulièrement le sujet de l'optimisation de l'accès aux données dans les architectures de type scale-out propices à la distribution, autant au niveau du modèle de données que des couches basses pour l'optimisation des I/O. Nous verrons également les concepts de développement à privilégier tel que le stateless dans la plus pure tradition REST. Je terminerai par quelques trucs et astuces en fin d'article. Le but est de vous permettre de constituer et d'optimiser votre infrastructure en comprenant le fonctionnement des outils proposés par Amazon pour en tirer le meilleur parti.

[...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-medium wp-image-1411 alignleft" title="Scale-Out in the Matrix" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/MatrixScaleOut-300x123.png" alt="Scale-Out in the Matrix" width="204" height="82" /></p>
<p>Comment scaler une infrastructure <a title="Site de Amazon Web Services" href="http://aws.amazon.com/">AWS</a> (Amazon Web Services) ? Je vais décrire dans cette deuxième partie de l&#8217;article le modèle de l&#8217;architecture et les composants techniques sous-jacents à adopter afin de mettre en place une infrastructure scalable. Nous aborderons tout particulièrement le sujet de l&#8217;optimisation de l&#8217;accès aux données dans les architectures de type scale-out propices à la distribution, autant au niveau du modèle de données que des couches basses pour l&#8217;optimisation des I/O. Nous verrons également les concepts de développement à privilégier tel que le stateless dans la plus pure tradition REST. Je terminerai par quelques trucs et astuces en fin d&#8217;article. Le but est de vous permettre de constituer et d&#8217;optimiser votre infrastructure en comprenant le fonctionnement des outils proposés par Amazon pour en tirer le meilleur parti.</p>
<p><strong><em>Le scale-out</em></strong><br />
<img class="size-full wp-image-1424 alignright" title="Scale-Up in Ghost Buster" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/GhostBusterScaleUp.jpg" alt="Scale-Up in Ghost Buster" width="116" height="170" />Le scale-out est à opposer au scale-up : ce dernier correspond à l&#8217;augmentation dynamique des ressources d&#8217;un serveur donné (ajout de RAM ou de CPU) à la volée. Ainsi l&#8217;application continue à s&#8217;exécuter sur une même machine dont le potentiel à augmenté. Le scale-out, lui, pour répondre à la montée en charge d&#8217;une application propose d&#8217;augmenter le nombre de serveurs. Au final, le potentiel global de l&#8217;infrastructure augmente aussi, mais est réparti entre plusieurs serveurs. Cela implique que l&#8217;application supportée sur le serveur ait été pensée en termes de distribution, c&#8217;est à dire qu&#8217;elle puisse s&#8217;exécuter en parallèle sur plusieurs serveurs sans que cela n&#8217;en corrompe la logique métier ou ne pose des problèmes d&#8217;accès aux ressources (qui doivent alors être disponibles via le réseau et non en local sur un serveur donné par exemple).</p>
<p>Le scale-out, c&#8217;est un peu l&#8217;agent Smith de Matrix. Pour le scale-up, pensez plutôt au gentil bibendum de Ghost Buster !</p>
<p><em><strong>Stateless</strong></em><br />
Le meilleur moyen d&#8217;obtenir une application facilement distribuable et performante est de la penser en mode stateless. C&#8217;est à dire que c&#8217;est la requête du client qui doit contenir l&#8217;ensemble des informations qui vont permettre le traitement de ladite requête côté serveur, soit via un cookie ou bien via les paramètres de l&#8217;URL. Quand cela est possible il faut privilégier cette approche à tout prix par rapport au mode stateful dans lequel la partie serveur doit maintenir un contexte pour chaque client afin de pouvoir résoudre sa requête. La conception stateless fait partie des grands concepts du REST. A ce sujet, je ne peux que vous conseiller de lire cet <a title="REST, un style d'architecture universel" href="http://www.figer.com/publications/REST.htm">excellent article sur REST</a> de Jean-Paul Figer dans lequel vous pourrez comprendre toute la simplicité et la puissance du style.</p>
<p>Si vous êtes obligés de gérer du stateful, il vous faudra utiliser un cache réseau, tel que <a title="Site de Memcached" href="http://memcached.org/">Memcached</a>, pour partager les contextes entre vos différents serveurs. N&#8217;envisagez pas la formule cache local et sticky session, car vous aurez du mal à bénéficier d&#8217;une répartition fluide au niveau de votre load balancing. N&#8217;envisagez pas non plus un cluster qui communique en multicast car le réseau Amazon ne permet pas d&#8217;en faire&#8230; Ou bien alors il faudrait que tous les serveurs communiquent en unicast avec une gateway qui s&#8217;occupe de la redistribution des communications&#8230; Vous êtes sûr que vous ne préférez pas du stateless ? ;ob</p>
<p>La mise en place d&#8217;applications stateless n&#8217;est pas arrivée avec le Cloud Computing et les AWS, en revanche ne pas penser dans ce sens, vous empêcherait de bénéficier de tout le dynamisme et la souplesse proposés par ces services.</p>
<p><em><strong>Optimisation de l&#8217;accès aux données</strong></em><br />
L&#8217;optimisation de l&#8217;accès aux données passe par 2 éléments :</p>
<ul>
<li>Le modèle de données et l&#8217;architecture logicielle que l&#8217;on retrouve  dans les architectures scalables, que l&#8217;on soit sur une infrastructure  AWS ou non.</li>
<li>La gestion des I/O que l&#8217;on peut optimiser, notamment via une utilisation approfondie des AWS.</li>
</ul>
<p><em><span style="text-decoration: underline;">Le modèle scalable</span></em><br />
Cela pourrait faire l&#8217;objet d&#8217;un article à part entière, mais correspond  à un modèle assez classique au sein des applications de type casual  gaming ou bien plus généralement liées à des applications basées sur les  graphes sociaux ou bien centrées sur une notion métier forte en particulier.</p>
<p>Pour résumer, 2 méthodes de stockage de données :</p>
<ul>
<li>Un stockage de ce que l&#8217;on peut appeler le méta-modèle, qui n&#8217;a pas  vocation à être distribué, basé sur une base relationnelle (même si  essentiellement utilisée sous forme d&#8217;accès clé-valeur) structurée,  indexée, contenant les informations générales de chaque utilisateur  (dans la cas d&#8217;une application sociale, avec les informations <em>nom</em>, <em>top score</em>, <em>gains de la veille</em>, &#8230;), essentiellement accédées en  lecture et dont il est possible d&#8217;alléger la charge via un Memcached en frontal. Il est donc possible d&#8217;effectuer des requêtes ensemblistes de type SQL et ainsi de récupérer des informations via l&#8217;utilisation de clauses (<em>WHERE</em>). Cette base peut être un MySQL ou un PgSQL par exemple. Je vous invite à lire ce <a title="Dotdeb, MySQL et Amazon : RDS vs EC2" href="http://www.dotdeb.org/2010/05/04/mysql-on-amazon-benchmarks-rds-vs-ec2/">comparatif très intéressant</a> de Guillaume Plessis entre l&#8217;utilisation de MySQL installé sur un <a title="Site de Amazon Web Services, Rubrique EC2" href="http://aws.amazon.com/ec2/">EC2</a> et l&#8217;utilisation du service <a title="Site de Amazon Web Services, Rubrique RDS" href="http://aws.amazon.com/rds/">RDS</a> (Relational Database Service) d&#8217;Amazon. Je ne trahirai en rien le suspens en vous disant que la base de données c&#8217;est une histoire de barbus ! :o)</li>
<li>Un stockage pour les données plus volatiles (comme les données de jeu, &#8230;), avec un fort rapport  écriture/lecture, difficilement cachables, et pour lesquelles il faut  opter pour une réelle solution de stockage structurée non relationnelle  de type clé-valeur (NoSQL / Not only SQL diront certains), permettant  ainsi de distribuer facilement les données sur X serveurs. On peut citer un nombre  certain de candidats : <a title="Site de Redis" href="http://code.google.com/p/redis/">Redis</a>, <a title="Site de Tokyo Tyrant" href="http://1978th.net/tokyotyrant/">Tokyo Tyrant</a>/<a title="Site de Tokyo Cabinet" href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a>, <a title="Site de MemcacheDB" href="http://memcachedb.org/">MemcacheDB</a>, &#8230; Et également les nouveaux modèles peer to peer tels que <a title="Site de Cassandra" href="http://cassandra.apache.org/">Cassandra</a>, &#8230;</li>
</ul>
<div id="attachment_1353" class="wp-caption alignright" style="width: 291px"><img class="size-full wp-image-1353" title="Tokyo Cabinet" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/TokyoCabinet.png" alt="Tokyo Cabinet" width="281" height="183" /><p class="wp-caption-text">Tokyo Cabinet</p></div>
<p>En l&#8217;occurrence, Tokyo Tyrant / Tokyo Cabinet est une solution que j&#8217;ai mise en place et qui me semble bonne. C&#8217;est un couple gérant respectivement les requêtes à partir de  serveurs distants (interface réseau) et les accès au système de  stockage. 6 APIs sont disponibles afin de stocker les données :</p>
<ol>
<li> On memory Hash,</li>
<li>On memory B+tree,</li>
<li>File Hash,</li>
<li>File B+tree,</li>
<li>Fixed-length Array,</li>
<li>Table.</li>
</ol>
<p>Chacune d’entre elles a ses propres spécificités et répond à des  besoins particuliers en termes de performances et de fonctionnalités.</p>
<p>Au niveau performances, outre ses performances naturelles, il a  l&#8217;avantage, notamment, de ne pas gérer l&#8217;authentification (standard chez les  systèmes de stockage clé-valeur, la sécurité est censée être assurée au niveau réseau pour les accès au système de stockage et au niveau applicatif pour les accès à la donnée &#8211; pour ne récupérer que ce qui vous concerne), ce qui allège le nombre d&#8217;accès (pas besoin de  requêtes d&#8217;authentification) par rapport à une base de données classique.  De plus, pas de gestion d&#8217;index lourds à reconstruire (possible  cependant sur l&#8217;API &laquo;&nbsp;Table&nbsp;&raquo; de la Tokyo Team), &#8230; Est-il nécessaire de préciser que ce  qui vous prendra du temps sur l’accès à la donnée via le réseau (entre  le serveur web ou applicatif et Tokyo Tyrant) c’est… Le réseau ! Donc  dans tous les cas, préférez l’utilisation au niveau client (API) de  « mget » (multi get), par exemple, en positionnant en paramètre le  tableau de clés que vous souhaitez récupérer, plutôt que d’effectuer N  fois un « get » à partir du client, donc N accès réseau. « mget » se  résoudra, lui, au niveau de Tokyo Tyrant.</p>
<p>Ces raisonnements appliqués sur cet outil doivent être appliqués à tout stockage de type clé-valeur.</p>
<p><span style="text-decoration: underline;"><em>La gestion des I/O</em></span><br />
Venons-en à la spécificité des AWS en termes de stockage : les <a title="Site de Amazon Web Services, Rubrique EBS" href="http://aws.amazon.com/ebs/">EBS</a> (Elastic Block Store). Les EBS sont des disques réseau optimisés en I/O, faciles à  manipuler, permettant d&#8217;assurer la durabilité des données qui ne doivent  pas être perdues lors de l&#8217;arrêt d&#8217;un EC2 (volatile). J&#8217;ai cependant  constaté de manière empirique des écarts de latence : pas énormes, mais  sur une application réellement sollicitée, il y a un ressenti.  Ce n&#8217;est pas rédhibitoire, il faut juste en tenir compte. Si le Load  Average de vos serveurs augmente, ce n&#8217;est pas forcément le CPU en  cause&#8230; Pensez I/O ! ;ob</p>
<p>Tout d&#8217;abord penser striping, donc RAID0. Pas besoin de mirroring (RAID1), la  durabilité des EBS est déjà assurée par Amazon, de manière transparente, par réplication réseau :  tirons parti de ce service et concentrons nous sur le striping. Pensez  également à répartir les écritures des différents fichiers physiques  (données, updates logs, …) sur différents disques (dans le cas d&#8217;outils  utilisant des update logs, et c&#8217;est le cas pour MySQL et Tokyo Tyrant  par exemple, pensez à bien paramétrer leur taille). C&#8217;est ce qui permet  d&#8217;avoir les meilleures optimisations. Ensuite, choisissez bien votre  système de fichier par rapport à votre outil (EXT3, XFS, …) et pensez  aux options de montage (noatime, nodiratime, &#8230;). Finalement vérifiez  bien le scheduler/ordonnanceur par défaut sur les instances EC2 que vous  démarrez : par défaut, il s&#8217;agit de l&#8217;ordonnanceur NOOP (requêtes I/O  dans une simple file FIFO). Envisagez quelque chose de plus performant  comme CFQ (Completely Fair Queuing) par exemple&#8230; Enfin je dis ça, mais cela dépend toujours de la couche logiciel au-dessus et si et comment elle gère les priorités : <a title="MySQL Performance Blog, Linux schedulers in tpcc like benchmark" href="http://www.mysqlperformanceblog.com/2009/01/30/linux-schedulers-in-tpcc-like-benchmark/">dans cet exemple</a> (qui n&#8217;est pas sur EBS) sur MySQL Performance Blog, il apparaît que les ordonnanceurs NOOP et DEADLINE peuvent être de meilleure facture pour améliorer les I/O InnoDB. Comme quoi, il faut quand même mieux tester dans son propre cas ! ;ob</p>
<div id="attachment_1177" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-1177" title="Logical Volume Management" src="http://decrypt.ysance.com/wp-content/uploads/2010/06/Archi_LVM-300x280.png" alt="Logical Volume Management" width="300" height="280" /><p class="wp-caption-text">Logical Volume Management</p></div>
<p>Un autre outil que j&#8217;ai utilisé avec les EBS et qui fonctionne très  bien est LVM2 (Logical Volume Management, version 2). Je ne l&#8217;ai pas  utilisé dans le cadre d&#8217;une architecture avec un nombre élevé d&#8217;IOPS (I/O operations Per Second) et n&#8217;ai donc pas  testé les possibilités de striping (RAID0) offertes par l&#8217;outil. En revanche, je l&#8217;ai utilisé dans  le cadre d&#8217;une infrastructure nécessitant de pouvoir supporter des  augmentations conséquentes du volume de données et ceci sans  interruption de service. L&#8217;opération de snapshot d&#8217;un EBS et de  recréation du volume est trop longue. LVM est la solution, puisque cette couche d&#8217;abstraction permet de gérer des volumes logiques de manière indépendante  des ressources physiques : il suffit de lever une nouvelle ressource EBS  (une ligne de commande), de l&#8217;associer à l&#8217;instance EC2 (une autre  ligne de commande) et d&#8217;ajouter cette ressource au pool de ressources  LVM. Il suffit alors d&#8217;agrandir le volume logique (toujours transparent et sans arrêt du service), puis  d&#8217;étendre le système de fichiers. C&#8217;est la dernière  opération (qui est commune avec celle de la recréation du volume EBS) qui peut nécessiter d&#8217;arrêter le service quelques instants (une dizaine de secondes). A noter qu&#8217;il est possible d&#8217;étendre son système de fichiers à chaud avec EXT3, personnellement, je préfère une interruption de service de quelques secondes sur ce genre d&#8217;opérations très courtes mais cruciales. ;ob En  prime, il est facile de d&#8217;effectuer des backups sur un système LVM qui  propose une option de snapshot différentiel que l&#8217;on peut monter comme  un volume logique indépendant : lorsqu&#8217;il y a une modification sur le  volume origine, la valeur initiale est copiée dans le volume snapshoté,  donc on peut snapshoter des volumes importants sur un espace réduit car  seule la fréquence de modification est importante. Vous pourrez trouver de plus amples informations sur LVM2 et EBS en consultant ce <a title="Decrypt, EBS et LVM2 ou comment optimiser l’élasticité des AWS" href="http://decrypt.ysance.com/2010/06/ebs-et-lvm2-ou-comment-optimiser-elasticite-des-aws/">très bon article</a> de Laurent Roux.</p>
<p>Tous ces exemples, pour montrer que les EBS sont une ressource très  intéressante : il faut les considérer tout d&#8217;abord comme un moyen d&#8217;assurer la durabilité des ressources importantes avant de considérer l&#8217;aspect performance. En effet, la performance n&#8217;est pas forcément meilleure sur un EBS que sur les disques locaux d&#8217;une instance EC2 (Cf. <a title="Ma petite présentation au Amazon web service french user group 2010" href="http://www.karlesnine.com/post/2010/05/07/Amazon-web-service-french-user-group-2010">un test simple et intéressant</a> de Charles-Christian Croix ou bien encore des tests un peu plus complexes que vous pourrez retrouver en tapant <em>&laquo;&nbsp;performance ephemeral disk ebs volume raid&nbsp;&raquo;</em> dans Google, il y en a un certain nombre de très intéressants et je dois avouer que j&#8217;ai du mal à faire mon choix ;ob). Cependant, quand on prend le parti d&#8217;assurer la durabilité de ses données et donc d&#8217;utiliser un EBS (qui, pour ceux qui connaissent, est comparable à un LUN sur un SAN), il y a divers moyens d&#8217;optimiser leur performance.</p>
<p>Il est à noter que les utiliser pour répartir les fichiers (et donc les I/O) sur plusieurs disques EBS peut être une solution de performance pure.</p>
<p>A noter tout de même que la bande passante de l&#8217;EC2 est forcément limitant arrivée à un certain seuil : ajouter des EBS est intéressant pour lisser les écarts de variance (en RAID0) ou bien pour optimiser le débit, mais il n&#8217;en reste pas moins que si vous ajoutez plusieurs EBS à votre instance EC2 et qu&#8217;ils sont tous sollicités fortement&#8230; C&#8217;est la bande passante de l&#8217;EC2 qui bloque. Il va falloir ajouter un nouvel EC2 (scale-out pour augmenter les ressources, en l&#8217;occurrence la bande passante), lui attacher de nouveaux EBS (n&#8217;oubliez pas qu&#8217;un EBS ne peut être attaché qu&#8217;à un et un seul EC2) et distribuer la donnée dessus (sharding).</p>
<p>Dans tous les cas, la manipulation des EBS est aisée et cette souplesse est un  atout.</p>
<p><em><strong>Tips &amp; tricks</strong></em><br />
Cette dernière partie regroupe quelques trucs et astuces.</p>
<p><em><span style="text-decoration: underline;">Alias &amp; IPs</span></em><br />
Pensez sur une infrastructure AWS à positionner des alias  correspondant aux IPs privées de vos instances dans le fichier des &laquo;&nbsp;hosts&nbsp;&raquo;, que vous pouvez déployer ensuite via <a title="Site de Puppet" href="http://www.puppetlabs.com/">Puppet</a> pour plus de réactivité vu que les IPs sont &laquo;&nbsp;variables&nbsp;&raquo; (lorsque vous arrêtez une instance et que vous en redémarrez une juste après, vous ne conservez pas la même IP). L&#8217;utilisation du  fichier &laquo;&nbsp;hosts&nbsp;&raquo; évite des résolutions DNS internes chez Amazon.</p>
<p><em><span style="text-decoration: underline;">CDN &amp; S3 Headers</span></em><br />
Pour les CDN (Content Delivery Network) que vous utilisez  obligatoirement dans une architecture scalable, pensez à utiliser S3 afin  de mettre à disposition les images et autres contenus statiques.  Inutile de maintenir un serveur Web à cette seule fin, S3 est là pour ça  pour un coût minime.</p>
<p>Pensez également dans certains cas, où votre trafic est plus modéré et où vous ne souhaitez pas passer par un CDN (pour des questions de coût par exemple ;ob), que vous pouvez toujours optimiser la gestion de vos ressources sur S3 en utilisant les méta-données attribuées aux dites ressources sur S3, en positionnant, par exemple, les headers de type <em>Cache-Control</em> ou <em>Expires</em>. Vous pouvez visualiser ces méta-données via le nouvel <a title="Site de Amazon Web Services, Console AWS, Onglet S3" href="https://console.aws.amazon.com/s3/home">onglet S3</a> de la console d&#8217;administration Amazon.</p>
<p><span style="text-decoration: underline;"><em>Backups&#8230;</em><em> What else ?</em></span><br />
S3 est également la solution pour les backups. Je n&#8217;ai pas trouvé  d&#8217;outils intégrés satisfaisants pour cette tâche : j&#8217;utilise simplement un  outil en ligne de commande &laquo;&nbsp;<a title="Site de s3tools, s3cmd" href="http://s3tools.org/s3cmd">s3cmd</a>&nbsp;&raquo; afin de stocker mes backups. J&#8217;ai intégré cet  outil dans des tâches <a title="Site de Capistrano" href="http://www.capify.org/">Capistrano</a> appelées par cron. Très  simple d’utilisation, s3cmd permet de consommer les services de S3 et offre la  possibilité de transférer les données en HTTPS et également de les  stocker sous un format crypté.</p>
<p><em><strong>Conclusion</strong></em><br />
Il y aurait encore beaucoup de choses à dire sur ce sujet, mais ce  sont à mon avis les principales, en tout cas par rapport à l&#8217;utilisation des services mis à disposition par les AWS. Ce qu&#8217;il en ressort, c&#8217;est :</p>
<ul>
<li>Le stateless et REST de manière générale, sont d&#8217;autant plus adaptés aux AWS qu&#8217;ils permettent de distribuer aisément la charge sur une infrastructure s&#8217;adaptant à la montée en charge sur un modèle scale-out.</li>
<li>L&#8217;accès aux données est toujours le goulet d&#8217;étranglement des applications distribuées devant scaler. Il s&#8217;agit de travailler à ce niveau le modèle de données et de tirer parti des systèmes de stockage adéquates :
<ul>
<li>Technologies SQL pour les méta-données pouvant nécessiter du requêtage ensembliste et de la mise en  relation, tout en utilisant au maximum un cache réseau pour les informations avec un fort ratio lecture sur écriture.</li>
<li>Technologies NoSQL / Not only SQL / clé-valeur pour les informations pouvant être accédées par une clé unique, et ainsi bénéficier de la distribution inhérente au scale-out.</li>
</ul>
</li>
<li>Penser finalement aux couches basses en sélectionnant convenablement le système de fichiers et l&#8217;ordonnanceur. Pensez également RAID (striping) et LVM (extension de volume et snapshot différentiel) pour tirer parti de la souplesse d&#8217;utilisation des EBS et répartition des I/O sur différents devices (en prenant toujours garde à votre bande passante, au niveau EC2, qui peut devenir limitant : dans ce cas ajouter une ou plusieurs instances EC2 pour gagner en bande passante et distribuer &#8211; sharder &#8211; la donnée sur de nouveaux EBS).</li>
</ul>
<p>J&#8217;espère que ce deuxième volet de mon retour d&#8217;expérience sur la scalabilité des infrastructures AWS vous aura intéressé.</p>
<p><em><strong>Frédéric FAURE</strong></em> <a title="Frédéric FAURE @Twitter" href="http://twitter.com/fredericfaure">@Twitter</a> <a title="Ysance, Simplifions les projets informatiques" href="http://www.ysance.com/">@Ysance</a></p>
]]></content:encoded>
			<wfw:commentRss>http://decrypt.ysance.com/2010/07/scaler-une-infrastructure-aws-2-le-modele/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tokyo Tyrant / Tokyo Cabinet, un key-value store à la Japonaise</title>
		<link>http://decrypt.ysance.com/2009/12/tokyo-tyrant-tokyo-cabinet-key-value-store-japonaise/</link>
		<comments>http://decrypt.ysance.com/2009/12/tokyo-tyrant-tokyo-cabinet-key-value-store-japonaise/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 15:20:34 +0000</pubDate>
		<dc:creator>Frédéric Faure</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Sharding / Partitionnement]]></category>
		<category><![CDATA[Redis]]></category>
		<category><![CDATA[Tokyo Cabinet]]></category>
		<category><![CDATA[Tokyo Tyrant]]></category>

		<guid isPermaLink="false">http://decrypt.ysance.com/?p=648</guid>
		<description><![CDATA[Les bases de données non relationnelles sont mises en avant depuis quelques temps avec un panel important de systèmes de stockage de la forme clé/valeur (key/value store). Cette approche permet d'avoir des structures optimisées pour certains types de fonctionnel et facilement distribuables. <a title="Site de Tokyo Cabinet" href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a> est un de ces outils. C'est un outil de stockage clé/valeur open source sponsorisé et utilisé par Mixi (Facebook japonais). Il a été développé par Mikio Hirabayashi que vous pouvez retrouver ainsi que l'exhaustivité des produits qu'il met à disposition sur <a title="Mikio Hirabayashi's homepage" href="http://1978th.net/">Mikio Hirabayashi's homepage</a>. Tokyo Cabinet est couplé à un autre produit : <a title="Site de Tokyo Tyrant" href="http://1978th.net/tokyotyrant/">Tokyo Tyrant</a>. Tokyo Tyrant est en fait l'interface réseau qui permet, entre autre, d'accéder à partir d'un serveur distant à Tokyo Cabinet. Il ne se limite cependant pas à cela et permet un certain nombre de fonctionnalités très intéressantes. Le point fort de ce couple est la rapidité de traitement des requêtes, ainsi que les possibilités de mise en oeuvre.

[...]]]></description>
			<content:encoded><![CDATA[<p>Les bases de données non relationnelles sont mises en avant depuis quelques temps avec un panel important de systèmes de stockage de la forme clé/valeur (key/value store). Cette approche permet d&#8217;avoir des structures optimisées pour certains types de fonctionnel et facilement distribuables. <a title="Site de Tokyo Cabinet" href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a> est un de ces outils. C&#8217;est un outil de stockage clé/valeur open source sponsorisé et utilisé par Mixi (Facebook japonais). Il a été développé par Mikio Hirabayashi que vous pouvez retrouver ainsi que l&#8217;exhaustivité des produits qu&#8217;il met à disposition sur <a title="Mikio Hirabayashi's homepage" href="http://1978th.net/">Mikio Hirabayashi&#8217;s homepage</a>. Tokyo Cabinet est couplé à un autre produit : <a title="Site de Tokyo Tyrant" href="http://1978th.net/tokyotyrant/">Tokyo Tyrant</a>. Tokyo Tyrant est en fait l&#8217;interface réseau qui permet, entre autre, d&#8217;accéder à partir d&#8217;un serveur distant à Tokyo Cabinet. Il ne se limite cependant pas à cela et permet un certain nombre de fonctionnalités très intéressantes. Le point fort de ce couple est la rapidité de traitement des requêtes, ainsi que les possibilités de mise en oeuvre.</p>
<p>Pour servir de support à cet article, je vous propose de regarder cette vidéo très intéressante de Ilya Grigorik, fondateur et CTO de AideRSS, que vous pourrez retrouver sur son blog <a title="Site de Ilya Grigorik" href="http://www.igvita.com/">igvita.com</a> (un blog très intéressant que je vous conseille de lire).</p>
<p>La <a title="Lean &amp; Mean Tokyo Cabinet Recipes" href="http://www.infoq.com/presentations/grigorik-tokyo-cabinet-recipes">VIDEO</a>.</p>
<p>Cette vidéo de 30 min, dans un anglais tout à fait abordable, est très intéressante, notamment sur les extensions de fonctionnalités rendues possibles par le langage de scripting Lua, intégrable au niveau de Tokyo Tyrant afin de permettre la mise en place de &laquo;&nbsp;user-defined fonctions&nbsp;&raquo; au niveau du serveur, centralisant les traitements et les rendant pseudo-atomiques. Je reviendrai dessus par la suite.</p>
<p><strong><em>Les APIs</em></strong><br />
Comme je vous le précisais, Tokyo Tyrant/Tokyo Cabinet est un couple gérant respectivement les requêtes à partir de serveurs distants (interface réseau) et les accès au système de stockage. 6 APIs sont disponibles afin de stocker les données :</p>
<ol>
<li>On memory Hash,</li>
<li>On memory B+tree,</li>
<li>File Hash,</li>
<li>File B+tree,</li>
<li>Fixed-length Array,</li>
<li>Table.</li>
</ol>
<p>Chacune d&#8217;entre elles a ses propres spécificités et répond à des besoins particuliers en termes de performances et de fonctionnalités.</p>
<p>Je ne paraphraserai pas la vidéo de Ilya Grigorik qui explique déjà un certain nombre de choses, mais apporterai quelques précisions.</p>
<p>Sur la notion de complexité des mécanismes de stockage Hash et B+tree (On memory ou File), les fonctions O(1) et O(log N) représentent la complexité d&#8217;accès à la donnée en fonction du nombre d&#8217;occurences stockées dans le système. On comprend bien que le comportement O(1) correspond bien à celui d&#8217;une hashtable, puisque le temps d&#8217;accès à la donnée ne dépend pas du nombre d&#8217;occurrences. En effet, la donnée est accédée directement à partir du hash de sa clé. Eventuellement, cette complexité peut varier si des collisions sur le hash apparaissent (2 clés différentes peuvent donner le même hash, à ce hash correspond alors une liste chainée de valeurs possibles). Il n&#8217;y a pas non plus d&#8217;index et donc de reconstruction d&#8217;index sur les insertions : donc gain de rapidité par rapport à une base de données classique. Pour plus de détail sur le fonctionnement des hashtables suivez ce <a title="Hash table, From Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Hash_table">lien</a>. Voici également 2 schémas issus de &laquo;&nbsp;Wikipedia, the free encyclopedia&nbsp;&raquo; expliquant la notion de hash et de collision :</p>
<div id="attachment_735" class="wp-caption alignnone" style="width: 325px"><img class="size-full wp-image-735" title="Hashtable" src="http://decrypt.ysance.com/wp-content/uploads/2009/12/Hashtable.png" alt="Hashtable" width="315" height="230" /><p class="wp-caption-text">Hashtable</p></div>
<div id="attachment_736" class="wp-caption alignnone" style="width: 460px"><img class="size-full wp-image-736" title="Hashtable - Collisions" src="http://decrypt.ysance.com/wp-content/uploads/2009/12/HashtableCollisions.png" alt="Hashtable - Collisions" width="450" height="310" /><p class="wp-caption-text">Hashtable - Collisions</p></div>
<p>La notion permettant d&#8217;évaluer la probabilité de collision est ce que l&#8217;on appelle la dispersion&#8230; Mais cela est un autre sujet ! ;ob</p>
<p>On comprend que le B+tree est donc un peu moins performant car sensible dans une certaine mesure (O(log N)) au nombre d&#8217;enregistrements. B+tree trouve son utilité dans le fait que le stockage est moins volumineux sur disque (ou en mémoire). Dans le cas du B+tree, les clés ne sont pas nécessairement uniques et il y a une notion de tri.</p>
<p>Pour le détail sur ces APIs, vous pouvez consulter la <a title="Fundamental Specifications of Tokyo Cabinet Version 1" href="http://1978th.net/tokyocabinet/spex-en.html">spécification</a>.</p>
<p><strong><em>Les performances</em></strong><br />
Il est à noter que les performances atteintes par Tokyo Cabinet seront probablement limitées du fait de l&#8217;utilisation de Tokyo Tyrant, puisque dans la majorité des cas vous aurez probablement à accéder au système de stockage à partir d&#8217;un serveur distant. Partez donc sur les performances affichées par Tokyo Tyrant qui, soit dit en passant, sont déjà considérables. Lors d&#8217;un bench que j&#8217;ai effectué sur le produit, je me suis aperçu que le load average de mon serveur hébergeant Tokyo Tyrant et Tokyo Cabinet était anormalement élevé&#8230; Pas à cause du CPU, mais à cause du disque qui ne répondait pas assez vite aux I/O débités par la Tokyo Team&#8230; Pensez à bien choisir votre système de fichier dans ce cas (type &#8211; EXT3, XFS, &#8230; -, journalisé ou non, options de montage, &#8230;) et n&#8217;hésitez pas à mettre du RAID0, par exemple, pour optimiser les performances en lecture/écriture ou bien à répartir les écritures des différents fichiers physiques (données, ulogs, &#8230;) sur différents disques.</p>
<p>Est-il nécessaire de préciser que ce qui vous prendra du temps sur l&#8217;accès à une donnée via le réseau c&#8217;est&#8230; Le réseau ! Hé oui ! Donc dans tous les cas préférez l&#8217;utilisation au niveau client (API) de &laquo;&nbsp;mget&nbsp;&raquo; (multi get), par exemple, en positionnant en paramètre le tableau de clés que vous souhaitez récupérer, plutôt que d&#8217;effectuer N fois un &laquo;&nbsp;get&nbsp;&raquo; à partir du client, donc N accès réseau. &laquo;&nbsp;mget&nbsp;&raquo; se résoudra, lui, au niveau serveur (Tokyo Tyrant).</p>
<p><strong><em>Les protocoles</em></strong><br />
Il est à noter que les protocoles HTTP et Memcached (et donc leurs APIs) sont directement utilisables afin d&#8217;accéder à Tokyo Tyrant, pas besoin de modifier le code de l&#8217;application pour passer d&#8217;un stockage on-memory sur <a title="Site de Memcached" href="http://memcached.org/">Memcached</a> à un stockage on-file sur Tokyo Tyrant/Tokyo Cabinet, par exemple. A noter que l&#8217;intégralité des fonctionnalités de Tokyo Tyrant ne seront donc pas forcément disponibles via le protocole Memcached ou HTTP, comme la concaténation, &#8230; Vous pouvez également utiliser le protocole natif binaire pour communiquer avec Tokyo Tyrant, ou bien avec Tokyo Cabinet si vous fonctionnez en &laquo;&nbsp;localhost&nbsp;&raquo;.</p>
<p><em><strong>Le requêtage ensembliste</strong></em><br />
En utilisant l&#8217;API Table, vous remarquerez qu&#8217;à chaque clé correspond un ensemble d&#8217;attributs, pas forcément le même nombre pour chaque clé (ces attributs peuvent être ajoutés à la volée et pas forcément valorisés pour les clés &laquo;&nbsp;antérieures&nbsp;&raquo;&#8230; Ni &laquo;&nbsp;postérieures&nbsp;&raquo; d&#8217;ailleurs). Il n&#8217;y a donc pas de schéma figé et chaque attribut peut faire l&#8217;objet d&#8217;une clause de requête ensembliste de type &laquo;&nbsp;WHERE&nbsp;&raquo;. Vous pourrez donc récupérer une liste de valeurs correspondant à des conditions sur un attribut et n&#8217;avez pas besoin de nommer explicitement la clé ou un pattern de clé afin de récupérer votre objet ou votre liste d&#8217;objets (cela n&#8217;est possible qu&#8217;avec l&#8217;API Table). Ce fonctionnement est similaire à celui que l&#8217;on peut retrouver sur <a title="Site de Amazon Web Services, Rubriques SimpleDB" href="http://aws.amazon.com/simpledb/">SimpleDB</a>, par exemple. A noter qu&#8217;il est aussi possible de positionner un index sur un attribut (Cf. vidéo de Ilya Grigorik).</p>
<p><strong><em>Lua</em></strong><br />
Lua&#8230; Lua !!! Un langage de scripting léger et efficace et comme le dit Ilya Grigorik : &laquo;&nbsp;C&#8217;est un mélange de Ruby et de Javascript&#8230; Enfin&#8230; Les mauvaises choses des 2 ! ;ob&nbsp;&raquo;. Cela explique probablement sa popularité : facile à utiliser, simple, efficace, &#8230; que demander de plus ? Il permet, par comparaison avec MySQL, de mettre en place des &laquo;&nbsp;user-defined fonctions&nbsp;&raquo;, à la différence qu&#8217;il s&#8217;agit d&#8217;un langage interprété qui ne provoquera pas le plantage du serveur Tokyo Tyrant sur une erreur ;ob. Il permet de mettre en place des opérations complexes comme par exemple :</p>
<ul>
<li>Renvoyer les données avec un format particulier (JSON, &#8230;).</li>
<li>Implémenter des fonctionnalités pseudo-atomiques au niveau serveur (c&#8217;est à dire atomique vu par le client = un seul appel réseau) afin de reproduire des fonctionnements tels que ceux du composant Set de <a title="Site de Redis" href="http://code.google.com/p/redis/">Redis</a>, un autre système de stockage clé/valeur montant l&#8217;intégralité de son dataset en mémoire (il faut tenir compte de ce point quand on choisit Redis au regard du volume de données que l&#8217;on doit stocker, mais rien n&#8217;empêche de distribuer le dataset sur plusieurs Redis) et assurant la persistance des données en écrivant de manière asynchrone sur le disque (soit suivant un délai, soit suivant un nombre de modifications effectuées sur ledit dataset). Concernant les types de données natifs sous Redis, vous pourrez notamment trouver les &laquo;&nbsp;List&nbsp;&raquo; qui sont des séquences d&#8217;éléments ordonnées et les &laquo;&nbsp;Set&nbsp;&raquo; (évoqués dans la vidéo) correspondant à une collection non-ordonnée sur laquelle on peut appliquer des opérations de type intersection, union, différence, &#8230; avec d&#8217;autres &laquo;&nbsp;Set&nbsp;&raquo;. Pour terminer cette digression permettant de comprendre l&#8217;exemple donné au cours de la vidéo, vous pouver consulter la <a title="Page de référence des commandes Redis" href="http://code.google.com/p/redis/wiki/CommandReference">Page de référence des commandes Redis</a>, ainsi que l&#8217;<a title="Introduction aux types de données Redis" href="http://code.google.com/p/redis/wiki/IntroductionToRedisDataTypes">Introduction aux types de données Redis</a>. Un exemple/tutoriel très intéressant est également disponible et présente la mise en place d&#8217;un clone de Twitter nommé Retwis : <a title="A case study: Design and implementation of a simple Twitter clone using only the Redis key-value store as database and PHP" href="http://code.google.com/p/redis/wiki/TwitterAlikeExample">A case study: Design and implementation of a simple Twitter clone using only the Redis key-value store as database and PHP</a>.</li>
<li>Implémenter une notion de TTL (Time To Live) comme dans Memcached. Cet exemple est basé sur l&#8217;utilisation de la Table API, puisqu&#8217;il faut un attribut supplémentaire ( &laquo;&nbsp;l&#8217;expiration time&nbsp;&raquo; ) qu&#8217;il est commode d&#8217;indexer pour des questions de performances (la possibilité d&#8217;introduire des index est noter pour cette API).</li>
</ul>
<p>A noter que ces implémentations, et notamment celle du Set, ne sont probablement pas aussi rapides qu&#8217;une fonctionnalité native, mais il est très pratique de pouvoir embarquer de la logique au niveau du serveur.<br />
A noter également la possibilité de démarrer le serveur Tokyo Tyrant en demandant un appel périodique (pc = periodic call) à ces &laquo;&nbsp;user-defined fonctions&nbsp;&raquo; en background. Pratique pour des opérations de purge, &#8230;</p>
<p><strong><em>MapReduce inside !</em></strong><br />
On note l&#8217;introduction du paradigm MapReduce à l&#8217;intérieur de Tokyo Tyrant, en natif, avec la possibilité de développer ses fonctions de Map et de Reduce en Lua.</p>
<p><strong><em>Réplication</em></strong><br />
Il est également possible de mettre en place de la réplication master-slave simplement entre 2 serveurs : quel beau couple qu&#8217;un master &laquo;&nbsp;on-memory&nbsp;&raquo; permettant d&#8217;optimiser les accès et un slave &laquo;&nbsp;on-file&nbsp;&raquo; assurant la persistance des données.</p>
<p>Voici les commandes permettant de mettre 2 serveurs en master-slave :</p>
<blockquote><p>ttserver -port 1978 -ulog ulog-1 -sid 1 casket-1.tch<br />
ttserver -port 1979 -ulog ulog-2 -sid 2 -mhost localhost -mport 1978 -rts 2.rts casket-2.tch</p></blockquote>
<p>Simple non ?</p>
<p><strong><em>Conclusion</em></strong><br />
Tokyo Tyrant / Tokyo Cabinet est un outil de stockage clé/valeur très intéressant, d&#8217;une part par ses performances et d&#8217;autre part par les possibilités d&#8217;évolutions qu&#8217;il offre en termes de fonctionnalités et de logique embarquée.</p>
<p>Cependant au delà de l&#8217;outil lui-même, il faut se poser la question en amont du modèle que l&#8217;on souhaite adopter vis à vis du fonctionnel de son application. Il est évident que si votre application peut s&#8217;adapter à un modèle clé/valeur, il est indispensable d&#8217;envisager cette possibilité, et c&#8217;est une des premières étapes à envisager au niveau de la conception. Je cite un de mes articles concernant le <a title="Sharding et optimisation des accès aux données" href="http://decrypt.ysance.com/2009/05/sharding-partitionnement-optimisation-acces-aux-donnees/">Sharding et optimisation des accès aux données</a> :</p>
<blockquote><p>Le sharding est une des solutions possible pour l’amélioration des temps de réponse sur ladite source d’éléments. Mais avant d’envisager cette solution, il est intéressant d’envisager d’autres possibilités dans cet ordre :</p>
<p>• le concept du modèle non relationnel, hébergé ou non, en général, puisque de ce choix découlera un autre modèle de fonctionnement,</p></blockquote>
<p>Le modèle clé/valeur est en effet un boost en termes de performances, si évidemment celui-ci correspond à votre fonctionnel. Cette question est à soulever rapidement et permettra de ne pas partir sur un modèle relationnel trop coûteux et sous exploité par certains types d&#8217;application.</p>
<p><strong><em>Frédéric FAURE</em></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://decrypt.ysance.com/2009/12/tokyo-tyrant-tokyo-cabinet-key-value-store-japonaise/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sharding et optimisation des accès aux données</title>
		<link>http://decrypt.ysance.com/2009/05/sharding-partitionnement-optimisation-acces-aux-donnees/</link>
		<comments>http://decrypt.ysance.com/2009/05/sharding-partitionnement-optimisation-acces-aux-donnees/#comments</comments>
		<pubDate>Thu, 28 May 2009 18:40:34 +0000</pubDate>
		<dc:creator>Frédéric Faure</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Sharding / Partitionnement]]></category>
		<category><![CDATA[Cassandra]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Partitionnement]]></category>
		<category><![CDATA[Proxy MySQL]]></category>
		<category><![CDATA[Réplication]]></category>
		<category><![CDATA[SimpleDB]]></category>

		<guid isPermaLink="false">http://decrypt.ysance.com/?p=172</guid>
		<description><![CDATA[Le sharding ou partitionnement de données entre dans le cadre plus global de la scalabilité. Il s’agit tout simplement du découpage des données d’une base afin d’avoir à requêter sur moins d’occurrences et donc d’avoir un résultat plus rapide donc de meilleures performances. Le sharding est une solution à part entière, mais qui ne convient pas dans tous les cas. Nous verrons également quelles sont les solutions alternatives pour une amélioration des temps de réponse au niveau d’une base de données.

[...]]]></description>
			<content:encoded><![CDATA[<p>Le sharding ou partitionnement de données entre dans le cadre plus global de la scalabilité. Il s’agit tout simplement du découpage des données d’une base afin d’avoir à requêter sur moins d’occurrences et donc d’avoir un résultat plus rapide donc de meilleures performances. Le sharding est une solution à part entière, mais qui ne convient pas dans tous les cas. Nous verrons également quelles sont les solutions alternatives pour une amélioration des temps de réponse au niveau d’une base de données.</p>
<p><strong><em>Pourquoi est-il si méchant ?</em></strong><br />
Oui ? Pourquoi vouloir à tout prix découper cette pauvre donnée dans tous les sens ? Quel est le déclencheur de cet acte barbare ?</p>
<p>Cela se produit simplement quand les temps de réponse des opérations sur une table fortement peuplée deviennent trop importants. Nous prendrons comme exemple une table « utilisateurs » comportant plusieurs millions de lignes. Depuis de nombreux SELECT en concurrence, qui unitairement ne présentent pas de performances dégradées malgré le nombre d’enregistrements, mais qui, sur de nombreuses requêtes, accumulent les latences, jusqu’aux INSERT demandant de reconstruire des INDEX monstrueux, où quelques insertions en trop sature la base, il y a de nombreuses raisons évidentes de vouloir découper son pool de données afin de pouvoir les manipuler plus légèrement.</p>
<p>Pour résumer, le besoin peut provenir de la masse de données elle-même ou bien du nombre/type de requêtes sur cette masse.</p>
<p>Il existe à ce niveau 2 techniques de sharding : le découpage en tranches et en lamelles…</p>
<p><strong><em>Découpage en tranches… ou horizontal</em></strong><br />
Le sharding horizontal consiste à répartir les données (lignes) d’une table cible entre plusieurs selon un critère basé sur une information liée à la donnée, par exemple un modulo sur l’identifiant qui permet de répartir les données sur X tables. Le tout est de savoir, au niveau de l’application cliente, sur quelle table aller chercher l’information. La clé et le plan de répartition sont , en effet, des éléments déterminants. La clé étant l’élément (ou les éléments) de la donnée à répartir sur lequel (ou lesquels) va porter le plan.</p>
<p>Plusieurs plans de répartition sont possibles sur une clé donnée :</p>
<p style="padding-left: 30px;">• Le modulo comme cité précédemment, ou autre fonction mathématique adaptée, est une option possible. Cependant, un changement du nombre de shard implique une redistribution complète. C’est cependant pratique si on doit définir la répartition sur un identifiant que l’on ne maitrise pas (récupéré d’un autre système ou fournisseur par exemple).</p>
<p style="padding-left: 30px;">• Dans la même idée, on peut répartir selon un algorithme de hash à définir soigneusement sur des valeurs non modifiables pour un objet donné à répartir et de telle manière que le calcul du hash soit rapide, le nombre de collisions entre 2 résultats minimum et la dispersion bonne. De même que précédemment, un changement du nombre de shard peut impliquer une redistribution complète. Cependant, des algorithmes appelés « consistants » existent. En utilisant des algorithmes de hash consistants, seulement K/n clés doivent être redistribuées en moyenne, où K est le nombre total de clés et n le nombre de shards.</p>
<p style="padding-left: 30px;">• Un « range », c&#8217;est-à-dire un intervalle, est aussi une solution. Pratique pour étendre le nombre de shard, il faut cependant maitriser l’identifiant retenu, un incrément par exemple, afin d’avoir une diffusion correcte.</p>
<p>D’autres méthodes peuvent êtres envisagées. Celles que j’ai citées sont les plus communes et les plus utilisées car elles répondent en général au besoin. La diffusion de la méthode retenue sur le critère choisi est dans tout les cas à vérifier pour une répartition efficace des données, c&#8217;est-à-dire qu’une répartition efficace aboutit à l’obtention de shards de tailles équivalentes. Le critère choisi pour répartir est généralement un identifiant, en effet, toute modification de la valeur déterminant la répartition, dans le cas d’un range ou bien intégrée dans le calcul d’un hash ou d’une fonction mathématique, ferait que l’objet ne serait plus accessible car pas enregistré dans le shard lui correspondant ou alors il faudrait le redispatcher…</p>
<p>Cette répartition peut se faire sur X tables dans une même base ou serveur ou bien sur 1 table dans Y bases ou serveurs (ou les 2 ;ob). Tout dépend du point d’engorgement. Est-ce purement le temps de réponse dû au volume de la table ? Ou bien atteint-on la limite physique du serveur qui peine à répondre à toutes ces requêtes ?</p>
<p>On en vient à la limitation de ce modèle pour lequel les requêtes ensemblistes posent problème. Je m’explique : on répartit les utilisateurs dans 2 tables en fonction du sexe : homme / femme. Je souhaite récupérer via une requête unitaire le Monsieur dont l’identifiant est X. Pas de problème je « SELECT * FROM UTILISATEUR_HOMME WHERE id=X ». Maintenant je souhaite récupérer toutes les personnes possédant un numéro de portable… Il va falloir faire la requête sur les 2 tables et corréler les résultats au niveau applicatif… dans des requêtes plus compliquées, notamment incluant des jointures, ce n’est pas forcément bénéfique. La parallélisation des requêtes, sur un sharding, au niveau applicatif est possible (quand le modèle de données le permet bien sûr), mais doit rester, à mon avis, mineur afin de ne pas perdre le bénéfice du sharding sur le temps de réponse pour une base donnée, en multipliant le nombre d’accès/connexions sur X sources et en traitant les résultats obtenus au niveau applicatif.</p>
<p>La répartition peut également engendrer des problèmes d’intégrité au niveau des données : la gestion des commit et des rollback est effective sur une connexion/transaction sur une base donnée. Comment gérer une transaction fonctionnelle qui s’étendrait sur plusieurs shard ? Commiter/rollbacker unitairement et prendre le risque d’une problématique d’intégrité ? Commiter/rollbacker chacune des connexions à la fin de la transaction fonctionnelle et conserver les connexions sur les X shards durant la transaction fonctionnelle et donc diminuer les capacités de connexions des X bases ?</p>
<p>Le problème de l’intégrité se pose également au niveau des backup/sauvegardes journalières, qui devront par conséquent s’effectuer lors d’une période de mise en maintenance (pas forcément longue) du site, nocturne par exemple. Il en va de même pour la restauration qui devra être effectuée, en cas de problème sur l’un des shards, sur l’ensemble des shards pour des problèmes d’intégrité.</p>
<p>On arrive enfin à la notion de « Single Point of Failure » dont le nombre augmentera avec le nombre de shards que vous mettrez en place sur des serveurs/machines différentes… A moins que vous ne fassiez de la réplication sur chacun des shards… Mais souvenez-vous qu’une solution efficace est bien souvent simple (ou tout du moins minimaliste) ! Alors…</p>
<p>Il n’y a pas de contre indication au sharding, il doit simplement être mesuré et prendre en compte les aspects précités afin d’être sûr que votre cas fonctionnel, et plus généralement votre besoin métier, accepte bien ce principe ou tout du moins en retire suffisamment de bénéfices pour valoir le jeu et être mis en place.</p>
<p><strong><em>Découpage en lamelles… ou vertical</em></strong><br />
Le sharding vertical se base sur une notion de temporalité. Plus simple à comprendre et à mettre en place, il dépend surtout de la typologie de votre site : un site marchand où 90% des visites du jour sont effectuées par des utilisateurs dont la connexion précédente à moins de 7 jours ou bien une administration dont 80% des dossiers consultés du jour l’ont déjà été dans les 2 dernières semaines. Ce n’est pas nécessaire de s’embêter à sharder si il n’y a pas de problématique de volumétrie, cependant, si le nombre d’informations trop important dans la table provoque des lenteurs sur la récupération/mise à jour/ajout d’informations et que la majeure partie des informations n’est que rarement utilisée… Bingo ! Il est intéressant de pouvoir donner à 90% (dans le premier cas) de vos visiteurs une expérience nettement meilleure tandis que les 10% restants auront une expérience quasi similaire, voire un peu dégradée dans le pire des cas.</p>
<p>L’étape la plus sensible sera de déterminer et d’ajuster au mieux la « coupure » de façon à satisfaire le plus grand nombre avec des performances optimales. C’est le moment d’analyser vos données et vos statistiques de fréquentation ! ;ob</p>
<p>Le mécanisme est très simple : quelque soit l’utilisateur, vous cherchez l’information dans la première table réduite contenant les données les plus accédées en un temps record, si elle y est tant mieux, sinon on requête dans la seconde table, celle des « archives ». il ne reste plus qu’à lancer un batch la nuit qui redispatche les éléments qui ont expiré de la table « courante » vers la table « archive » et de ramener les éléments archivés consultés ce jour vers la table courante.</p>
<p>Cette technique n’est absolument pas faite pour parer au problème du nombre d’accès/connexions à la base comme peut l’être le sharding horizontal, puisque le but est justement de satisfaire le plus rapidement possible la majeure partie des connexions à la dite base. Le but est purement de limiter la volumétrie d’une source de données pour en accélérer les traitements/requêtes dessus.</p>
<p>De plus, dans le cas de requêtes ensemblistes portant sur les 2 « zones », le problème est similaire à celui du découpage horizontal.</p>
<p><strong><em>Un petit cube, 2 petits cubes, …</em></strong><br />
Et les 2 en même temps ? Oui c’est possible ! Mais il faut satisfaire aux pré-requis des 2 cas et en accepter les bénéfices et inconvénients.</p>
<p><strong><em>Alternatives</em></strong><br />
Les alternatives proviennent du fait que le sharding répond à un besoin : celui d’améliorer les temps de réponse sur les accès aux sources de données. Mais d’autres solutions existent…</p>
<p><em><span style="text-decoration: underline;">L’essentiel tuning de base<br />
</span></em>Avant de se lancer dans du sharding et autres solutions plus complexes… Avez-vous paramétré convenablement votre base en fonction de l’utilisation que vous en faites ? Vous seriez surpris des différences que l’on peut obtenir… C’est LA première étape avant d’aller plus loin et d’envisager le sharding ou une autre solution. Une base convenablement tunée vous suffira peut-être.</p>
<p>Ensuite intéressez-vous au type de stockage. Il influe sur les performances en fonction des opérations effectuées. J’ai étudié le problème sur MySQL et constaté les différences flagrantes, en pratique, entre InnoDB et MyISAM. Pour les tables essentiellement accédées en lecture, MyISAM est fait pour. En revanche, pour celles accédées en écriture, InnoDB, avec son système de row locking, vous donnera bien meilleure satisfaction.</p>
<p>C’est LE conseil que je peux vous donner à cette étape : maitrisez d’abord votre outil de base (sans jeu de mots) avant de vouloir ajouter une couche de complexité, parfois nécessaire… Mais pas tout le temps.</p>
<p><em><span style="text-decoration: underline;">Le classique Master-Slave</span></em><br />
Le classique Master-Slave, encore appelé réplication, vous permettra d’optimiser des problèmes de temps de réponse dus au nombre de connexions/requêtes sur une table à forte volumétrie, où l’écriture peut prendre du temps du fait de la reconstruction d’index sur les INSERT par exemple et ce faisant influant sur les temps de réponse des lectures (SELECT) et vice-versa , en séparant la lecture de l’écriture : typiquement l’écriture s’effectuera sur le master et la lecture sur le slave (ou les slaves).</p>
<p><em><span style="text-decoration: underline;">L’éventuel partitionnement MySQL</span></em><br />
Depuis la version 5.1, MySQL propose un partitionnement (ou sharding) géré nativement. Ne l’ayant pas testé par moi-même, je ne pourrais vous donner de retour sur le sujet. Le partitionnement proposé par l’outil est horizontal. Il est à noter que la notion de partitionnement vertical est différente de celle que je vous est présentée dans la sémantique MySQL : il s’agit de pouvoir stocker sur différentes partitions les colonnes d’une même table, par exemple les colonnes de type standard d’une table donnée sur une partition et la colonne de type BLOB sur une autre. Dans tous les cas, le partitionnement vertical n’est pas assuré dans la version 5.1 de MySQL. Même si cela peut paraître attrayant, je pense qu’il est moins limitant de sharder soi-même et qu’il est rassurant de conserver la main sur la répartition des données que l’on souhaite et de pouvoir intervenir en toute connaissance de cause, sans se soucier, par exemple, de la version de la base et donc de la version de la fonctionnalité de partitionnement associée qui sous-tend la répartition des données, lors d’une montée de version… Je ne pense pas non plus qu’il soit possible d’effectuer un partitionnement « multi serveurs » afin de répartir le nombre de connexions entre diverses machines… Mais bon j’ai pas testé alors…</p>
<p><em><span style="text-decoration: underline;">Le « hors sujet » MySQL Proxy</span></em><br />
Compatible avec les versions 5.0.x de MySQL, cet outil est en version alpha et donc ne convient pas à un environnement de production. Mais le « hors sujet » ne provient pas de là mais du fait que cet outil traite de load balancing sur plusieurs backend (probablement des réplicats d’un master servant à une optimisation en lecture sur X slaves), de failover, et d’« injection SQL » permettant au niveau du proxy d’ajouter des clauses d’analyse aux requêtes ou bien de filtrer les résultats, … C’est l’équivalent d’un proxy web qui répartit la charge, gère le statut des backends et modifie les requêtes. Alors pourquoi est-ce que je parle de ça ? Hors sujet : 0/20 ! C’est uniquement parce que j’en ai entendu parler plusieurs fois de la part de clients et qu’il y avait une confusion sur son utilité. Le Proxy MySQL NE permet PAS de faire de la répartition de données.</p>
<p><em><span style="text-decoration: underline;">L’indispensable cache mémoire</span></em><br />
Je prendrai l’exemple de <a href="http://www.danga.com/memcached/" title="Site de Memcached">Memcached</a> qui est un cache de données réseau pour objets génériques. Memcached est le cache que j’utilise et qui a fait ses preuves. Maintenant, libre à vous d’utiliser d’autres outils ou bien même de réaliser vous-même votre système de cache mémoire adapté à votre utilisation, pour peu que vous en ayez l’envie et le temps. Dans tout les cas, votre cache mémoire vous permettra de limiter le nombre d’accès au système de stockage plus lent qu’est la base de données, en conservant un certain nombre de résultats dans une « hashtable géante ». En diminuant le nombre de requêtes sur vos tables volumineuses, cela suffira peut-être à obtenir des temps de réponse convenables et à ne pas saturer votre serveur en connexions, vous permettant ainsi de ne pas avoir à sharder.</p>
<p><em><span style="text-decoration: underline;">Le surprenant modèle non relationnel hébergé et SimpleDB</span></em><br />
Et oui ! Remis au goût du jour par Google avec BigTable et Amazon avec <a href="http://aws.amazon.com/simpledb/" title="Site de Amazon, rubrique SimpleDB">SimpleDB</a>, le modèle non relationnel prouve toute son efficacité et sa scalabilité. Si vous n’avez effectivement pas besoin des jointures et autres relations, c’est peut-être votre solution. Et pourquoi pas utiliser l’API Amazon pour SimpleDB et profiter de l’infrastructure et des services Amazon ?</p>
<p><em><span style="text-decoration: underline;">Les prometteuses innovations distribuées et Cassandra</span></em><br />
A rapprocher de SimpleDB car développé sur un modèle similaire à Dynamo, la technologie qui sous-tend simpleDB. <a href="http://incubator.apache.org/cassandra/" title="Site de Cassandra">Cassandra</a> est un système de stockage de données, structuré mais non relationnel, basé sur un réseau P2P (« peer to peer » ou « pair à pair » en Français ;ob). Il s’agit d’un système distribué sous forme de nodes, fortement scalable, et dont la particularité est qu’il est actuellement accessible au format Open Source. Développé par Facebook et actuellement en production chez eux, Cassandra est en version Beta et accessible dans le projet « Apache incubator » (Cf. liste de liens de la rubrique « Outils » de Decrypt : « Cassandra »). Vous pouvez également consulter cette note <a href="http://www.facebook.com/note.php?note_id=24413138919">http://www.facebook.com/note.php?note_id=24413138919</a> pour de plus amples informations. Il est surtout intéressant que l’explosion des applications et réseaux sociaux ait un impact sur la mise à disposition d’outils de stockage et de gestion de données fortement scalables. Cette tendance (augmentation de la volumétrie des données) va s’étendre à d’autres domaines du fait de la croissance des sources de données informatisées et de l’évolution des services. Les architectures distribuées se propagent jusqu’à la source… de données, dernier goulet d’étranglement des architectures scalables. Je pense cependant que le sujet de la scalabilité du système de stockage de données restera encore le point le plus ardu à mettre en place, pour un bout de temps, dans toute architecture.</p>
<p><strong><em>Conclusion</em></strong><br />
On constate que le sharding répond à un besoin bien particulier. Il concerne dans tous les cas une ou des tables contenant un volume important de données. Les lenteurs au niveau des temps de réponse peuvent être induites par le volume de données lui-même ou bien/et par le nombre d’utilisateurs s’y connectant de ce fait (dans le cas d’un site grand public). Le sharding est une des solutions possible pour l’amélioration des temps de réponse sur ladite source d’éléments. Mais avant d’envisager cette solution, il est intéressant d’envisager d’autres possibilités dans cet ordre :</p>
<p style="padding-left: 30px;">• le concept du modèle non relationnel, hébergé ou non, en général, puisque de ce choix découlera un autre modèle de fonctionnement,</p>
<p style="padding-left: 30px;">• le tuning de la base de données pour optimiser le socle de votre problématique,</p>
<p style="padding-left: 30px;">• le cache mémoire, simple de mise en place et terriblement efficace pour limiter les connexions inutiles sur votre source de données et livrer les informations en un temps record,</p>
<p style="padding-left: 30px;">• la réplication master-slave, classique mais efficace, dans la même optique de limitation du nombre de requêtes sur une base donnée,</p>
<p style="padding-left: 30px;">• les fonctionnalités de partitionnement livrées en natif avec le produit, potentiellement utiles, potentiellement limitées…</p>
<p style="padding-left: 30px;">• finalement le sharding (ou partitionnement) fait main ou plutôt les sharding, vertical et horizontal, pour limiter la volumétrie de la ou des tables, et par là même limiter le nombre de requêtes sur ladite ou lesdites tables dans le cas du sharding horizontal.</p>
<p>Il est tout à fait possible de composer en utilisant le cache mémoire avec la réplication, ou bien le cache mémoire avec un ou les 2 sharding… Le tout est de cibler son problème, le point d’engorgement et donc son besoin, pour utiliser la ou les techniques adéquates. Si une seule suffit, tant mieux.</p>
<p>Le sharding de données fait donc partie intégrante d’un problème plus global et est une solution tout à fait viable, demandant tout de même « un peu » de réflexion et de temps de mise en place et impactant dans la conception et la maintenance de l’infrastructure. Il est donc à utiliser à bon escient, mais se révèle fort utile et très efficace.</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/05/sharding-partitionnement-optimisation-acces-aux-donnees/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

