<?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>Swift Archives - OVHcloud Blog</title>
	<atom:link href="https://blog.ovhcloud.com/tag/swift/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.ovhcloud.com/tag/swift/</link>
	<description>Innovation for Freedom</description>
	<lastBuildDate>Tue, 21 Jan 2020 16:02:32 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.ovhcloud.com/wp-content/uploads/2019/07/cropped-cropped-nouveau-logo-ovh-rebranding-32x32.gif</url>
	<title>Swift Archives - OVHcloud Blog</title>
	<link>https://blog.ovhcloud.com/tag/swift/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Dealing with small files with OpenStack Swift (part 2)</title>
		<link>https://blog.ovhcloud.com/dealing-with-small-files-with-openstack-swift-part-2/</link>
		
		<dc:creator><![CDATA[Alexandre Lecuyer]]></dc:creator>
		<pubDate>Fri, 17 Jan 2020 09:16:09 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">https://www.ovh.com/blog/?p=16151</guid>

					<description><![CDATA[In the first part of these articles, we demonstrated how storing small files in Swift may cause performance issues. In this second part we will present the solution. With this in mind, I will assume that you have read the first part, or that you are familiar with Swift. Files inside files We settled on [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fdealing-with-small-files-with-openstack-swift-part-2%2F&amp;action_name=Dealing%20with%20small%20files%20with%20OpenStack%20Swift%20%28part%202%29&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<p>In the<a href="https://www.ovh.com/blog/dealing-with-small-files-with-openstack-swift-part-1/" data-wpel-link="exclude"> first part of these articles</a>, we demonstrated how storing small files in Swift may cause performance issues. In this second part we will present the solution. With this in mind, I will assume that you have read the first part, or that you are familiar with Swift.<br></p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img fetchpriority="high" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-1024x513.jpeg" alt="Swift at OVHcloud" class="wp-image-16063" width="512" height="257" srcset="https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-1024x513.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-300x150.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-768x385.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929.jpeg 1199w" sizes="(max-width: 512px) 100vw, 512px" /></figure></div>



<h3 class="wp-block-heading">Files inside files</h3>



<p>We settled on a simple approach: we would store all these small fragments in larger files. This means that inodes usage on the filesystem is much lower. <br></p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/01/E65EF82E-7465-4791-AF4D-23E67D0DC1E6-1024x273.jpeg" alt="" class="wp-image-16757" width="512" height="137" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/01/E65EF82E-7465-4791-AF4D-23E67D0DC1E6-1024x273.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/01/E65EF82E-7465-4791-AF4D-23E67D0DC1E6-300x80.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/01/E65EF82E-7465-4791-AF4D-23E67D0DC1E6-768x205.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/01/E65EF82E-7465-4791-AF4D-23E67D0DC1E6.jpeg 1220w" sizes="(max-width: 512px) 100vw, 512px" /></figure></div>



<p>These large files, which we call “volumes”, have three important characteristics:</p>



<ul class="wp-block-list"><li>They are dedicated to a Swift partition</li><li>They are append only: never overwrite data</li><li>No concurrent writes: we may have multiple volumes per partition</li></ul>



<p>We need to keep track of the location of these fragments within a volume. For this we developed a new component: the index-server. This will store each fragment location: the volume it is stored in, and its offset within the volume. </p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/01/4147A20D-7993-4079-903C-A07FC94BEA81.jpeg" alt="" class="wp-image-16759" width="398" height="293" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/01/4147A20D-7993-4079-903C-A07FC94BEA81.jpeg 795w, https://blog.ovhcloud.com/wp-content/uploads/2020/01/4147A20D-7993-4079-903C-A07FC94BEA81-300x221.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/01/4147A20D-7993-4079-903C-A07FC94BEA81-768x565.jpeg 768w" sizes="(max-width: 398px) 100vw, 398px" /></figure></div>



<p>There is one index-server per disk drive. This means that its failure domain matches with the data it is indexing. It communicates with the existing object-server process through a local UNIX socket.</p>



<h4 class="wp-block-heading">Leveraging on LevelDB </h4>



<p>We chose LevelDB to store the fragment location in the index-server:</p>



<ul class="wp-block-list"><li>It sorts data on-disk, which means it is efficient on regular spinning disks</li><li>It is space efficient thanks to the Snappy compression library</li></ul>



<p>Our initial tests were promising: it showed that we need about 40 bytes to track a fragment, vs 300 bytes if we used the regular file-based storage backend. We only track the fragment location, while the filesystem stores a lot of information that we don&#8217;t need (user, group, permissions..) This means the key-value would be small enough to be cached in memory, and listing files would not require physical disk reads.</p>



<p>When writing an object, the regular swift backend would create a file to hold the data. With LOSF, it would instead:</p>



<ul class="wp-block-list"><li>Obtain a filesystem lock on a volume</li><li>Append the object data at the end of the volume, and call fdatasync()</li><li>Register the object location in the index-server (volume number, and offset within volume)</li></ul>



<p>To read back an object:</p>



<ul class="wp-block-list"><li>Query the index-server to get its location: volume number and offset</li><li>Open the volume and seek to the offset to serve the data</li></ul>



<p>However, we still have a couple of problems to solve!<br></p>



<h3 class="wp-block-heading">Deleting objects</h3>



<p>When a customer deletes an object, how can we actually delete data from the volumes? Remember that we only append data to a volume, so we can&#8217;t just mark space as unused within a volume, and try to reuse it later. We use XFS, and it offers an interesting solution: The ability to “punch a hole” in a file.<br></p>



<p>The logical size does not change, which means that fragments located after the hole do not change offset. The physical space, however, is released to the filesystem. This is a great solution, as it means we can keep appending to volumes, free space within a volume, and let the filesystem deal with space allocation.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/01/643F85AA-C543-4F90-BD10-D6F34D41287F.jpeg" alt="" class="wp-image-16762" width="377" height="238" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/01/643F85AA-C543-4F90-BD10-D6F34D41287F.jpeg 754w, https://blog.ovhcloud.com/wp-content/uploads/2020/01/643F85AA-C543-4F90-BD10-D6F34D41287F-300x189.jpeg 300w" sizes="auto, (max-width: 377px) 100vw, 377px" /></figure></div>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/01/314F81C4-F129-48AE-93A0-B707D2C021CE.jpeg" alt="" class="wp-image-16763" width="375" height="359" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/01/314F81C4-F129-48AE-93A0-B707D2C021CE.jpeg 749w, https://blog.ovhcloud.com/wp-content/uploads/2020/01/314F81C4-F129-48AE-93A0-B707D2C021CE-300x288.jpeg 300w" sizes="auto, (max-width: 375px) 100vw, 375px" /></figure></div>



<h2 class="wp-block-heading">Directory structure</h2>



<p>The index-server will store object names in a flat namespace, but Swift relies on a directory hierarchy.</p>



<pre class="wp-block-code"><code class="">/mnt/objects/&lt;partition>/&lt;suffix>/&lt;checksum>/&lt;timestamp>.data</code></pre>



<p>The partition directory is the partition which the object belongs to, and the suffix directory is just the last three letters of the md5 checksum. (This was done to avoid having too many entries in a single directory)</p>



<p>If you have not used Swift before, the &#8220;partition index&#8221; of an object indicates which device in the cluster should store the object. The partition index is calculated by taking a few bits from the object&#8217;s path MD5. You can find out more <a href="https://docs.openstack.org/swift/latest/overview_ring.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">here</a>.<br></p>



<p>We do not explicitely store these directories in the index-server, as they can be computed from the object-hash. Remember that the object names are stored in order by LevelDB.</p>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://docs.google.com/drawings/d/sXCQOPWYjWdZxRKyoCQCBMg/image?w=602&amp;h=292&amp;rev=263&amp;ac=1&amp;parent=1UwtIisZKQcstTlIOKYX6I17U7bH4mCtg6uIC7xcY2mM" alt="" width="809" height="392"/></figure>



<h3 class="wp-block-heading">Data migration</h3>



<p>This new approach changes the on-disk format. However we already had over 50 PB of data. Migrating offline was impossible. We wrote an intermediate, hybrid version of the system. It would always write new data using the new disk layout, but for reads, it would first look up in the index-server, and if the fragment wasn’t found, it would look up the fragment in the regular backend directory.</p>



<p>Meanwhile, a background tool would run to slowly to convert data from the old system to the new one. This took a few months to run over all machines.</p>



<h3 class="wp-block-heading">Results</h3>



<p>After the migration completed, the disk activity on the cluster was much lower: we observed that the index-server data would fit in memory, so listing objects in the cluster, or getting an object&#8217;s location would not require physical disk IO. The latency improved for both PUT and GET operations, and the cluster &#8220;reconstructor&#8221; tasks were able to progress much faster. (The reconstructor is the process that rebuilds data after a disk fails in the cluster)</p>



<h3 class="wp-block-heading">Future work</h3>



<p>In the context of object storage, hard drives still have a price advantage over solid state drives. Their capacity continues to grow, however the performance per drive has not improved. For the same usable space, if you switch from 6TB to 12TB drives, you&#8217;ve effectively halved your performance. </p>



<p>As we plan for the next generation of Swift clusters, we must find new ways to use these larger drives while ensuring performance is still good. This will probably mean using a mix of SSDs and spinning disks. Exciting work is happening in this area, as we will store more data on dedicated fast devices to further optimise Swift&#8217;s cluster response time.</p>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fdealing-with-small-files-with-openstack-swift-part-2%2F&amp;action_name=Dealing%20with%20small%20files%20with%20OpenStack%20Swift%20%28part%202%29&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dealing with small files with OpenStack Swift (part 1)</title>
		<link>https://blog.ovhcloud.com/dealing-with-small-files-with-openstack-swift-part-1/</link>
		
		<dc:creator><![CDATA[Alexandre Lecuyer]]></dc:creator>
		<pubDate>Fri, 04 Oct 2019 08:37:39 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">https://www.ovh.com/blog/?p=16037</guid>

					<description><![CDATA[OpenStack Swift is a distributed storage system that is easy to scale horizontally, using standard servers and disks. We are using it at OVHcloud for internal needs, and as a service for our customers. By design, it is rather easy to use, but you still need to think about your workload when designing a Swift [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fdealing-with-small-files-with-openstack-swift-part-1%2F&amp;action_name=Dealing%20with%20small%20files%20with%20OpenStack%20Swift%20%28part%201%29&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<p>OpenStack Swift is a distributed storage system that is easy to scale horizontally, using standard servers and disks.</p>



<p>We are using it at OVHcloud for internal needs, and as a service for our customers.<br></p>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="513" src="https://www.ovh.com/blog/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-1024x513.jpeg" alt="Swift at OVHcloud" class="wp-image-16063" srcset="https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-1024x513.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-300x150.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929-768x385.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/E53A8B26-BDF1-43A9-9A64-5C38029C9929.jpeg 1199w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>By design, it is rather easy to use, but you still need to think about your workload when designing a Swift cluster. In this post I’ll explain how data is stored in a Swift cluster, and why small objects are a concern.<br></p>



<h3 class="wp-block-heading">How does Swift store files?</h3>



<p>The nodes responsible for storing data in a Swift cluster are the “object servers”. To select the object servers that will hold a specific object, Swift relies on <a href="https://en.wikipedia.org/wiki/Consistent_hashing" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">consistent hashing</a>: </p>



<p></p>



<p>In practice, when an object is uploaded, a MD5 checksum will be computed, based on the object name. A number of bits will be extracted from that checksum, which will give us the “partition” number.&nbsp;<br></p>



<p>The partition number enables you to look at the “ring”, to see which server and disk should store that particular object. The “ring” is a mapping between a partition number, and the object servers that should store objects belonging to that partition.<br></p>



<p>Let’s take a look at an example. In this case we will use only 2 bits off the md5 checksum (far too low but much easier to draw! There are only 4 partitions)<br></p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="564" src="https://www.ovh.com/blog/wp-content/uploads/2019/10/00FE1332-E324-4E49-9E6E-0FA7E6C27E81-1024x564.jpeg" alt="" class="wp-image-16064" srcset="https://blog.ovhcloud.com/wp-content/uploads/2019/10/00FE1332-E324-4E49-9E6E-0FA7E6C27E81-1024x564.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/00FE1332-E324-4E49-9E6E-0FA7E6C27E81-300x165.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/00FE1332-E324-4E49-9E6E-0FA7E6C27E81-768x423.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/00FE1332-E324-4E49-9E6E-0FA7E6C27E81.jpeg 1227w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p></p>



<p></p>



<p>When a file is uploaded, from its name and other elements, we get a md5 checksum, <code>72acded3acd45e4c8b6ed680854b8ab1</code>. If we take the 2 most significant bits, we get partition 1.&nbsp;</p>



<p>From the object ring, we get the list of servers that should store copies of the object.&nbsp;</p>



<p>With a recommended Swift setup, you would store three identical copies of the object. For a single upload, we create three actual files, on three different servers.<br></p>



<h3 class="wp-block-heading">Swift policies</h3>



<p>We’ve just seen how the most common Swift policy is to store identical copies of an object.<br></p>



<p>That may be a little costly for some use cases, and Swift also supports “erasure coding” policies.<br></p>



<p>Let’s compare them now.<br></p>



<p>The “replica policy” which we just described. You can choose how many copies of objects you want to store.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="885" src="https://www.ovh.com/blog/wp-content/uploads/2019/10/407D94D3-DCA9-4F2B-B34B-82FBD8D89186-1024x885.jpeg" alt="Replica in Swift" class="wp-image-16071" srcset="https://blog.ovhcloud.com/wp-content/uploads/2019/10/407D94D3-DCA9-4F2B-B34B-82FBD8D89186-1024x885.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/407D94D3-DCA9-4F2B-B34B-82FBD8D89186-300x259.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/407D94D3-DCA9-4F2B-B34B-82FBD8D89186-768x664.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/407D94D3-DCA9-4F2B-B34B-82FBD8D89186.jpeg 1290w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The “erasure coding” policy type</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="918" height="1024" src="https://www.ovh.com/blog/wp-content/uploads/2019/10/14C000A4-B7C0-4C80-B394-D9884C8765A6-918x1024.jpeg" alt="Erasure coding in Swift" class="wp-image-16072" srcset="https://blog.ovhcloud.com/wp-content/uploads/2019/10/14C000A4-B7C0-4C80-B394-D9884C8765A6-918x1024.jpeg 918w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/14C000A4-B7C0-4C80-B394-D9884C8765A6-269x300.jpeg 269w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/14C000A4-B7C0-4C80-B394-D9884C8765A6-768x856.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2019/10/14C000A4-B7C0-4C80-B394-D9884C8765A6.jpeg 1269w" sizes="auto, (max-width: 918px) 100vw, 918px" /></figure>



<p>The object is split into fragments, with added redundant pieces to enable object reconstruction, if a disk containing a fragment fails.</p>



<p>At OVHcloud, we use a 12+3 policies (12 pieces from the object and 3 computed pieces)<br></p>



<p>This mode is more space efficient than replication, but it also creates more files on the infrastructure. In our configuration, we would create 15 files on the infrastructure, vs 3 files with a standard “replication” policy.</p>



<h3 class="wp-block-heading">Why is this a problem?</h3>



<p>On clusters where we have a combination of both an erasure coding policy, and a median object size of 32k, we would end up with over 70 million files *per drive*.</p>



<p>On a server with 36 disks, that’s 2.5 billion files.<br></p>



<p>The Swift cluster needs to regularly list these files to:</p>



<ul class="wp-block-list"><li>Serve the object to customers</li><li>Detect bit rot</li><li>Reconstruct an object if a fragment has been lost because of a disk failure</li></ul>



<p>Usually, listing files on a hard drive is pretty quick, thank’s to Linux’s directory cache. However, on some clusters we noticed the time to list files was increasing, and a lot of the hard drive’s IO capacity was used to read directory contents: there were too many files, and the system was unable to cache the directory contents. Wasting a lot of IO for this meant that the cluster response time was getting slower, and reconstruction tasks (rebuilding fragments lost because of disk failures) were lagging.</p>



<p>In the next post we&#8217;ll see how we addressed this.</p>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fdealing-with-small-files-with-openstack-swift-part-1%2F&amp;action_name=Dealing%20with%20small%20files%20with%20OpenStack%20Swift%20%28part%201%29&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
