<?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>Art Blog &#187; image generation</title>
	<atom:link href="http://blog.artweb.com/tag/image-generation/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.artweb.com</link>
	<description>Artist Centric Art Blog</description>
	<lastBuildDate>Tue, 07 Feb 2012 13:20:54 +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>Do&#8217;s and Dont&#8217;s for scaleable image hosting</title>
		<link>http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/</link>
		<comments>http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 14:46:06 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[amazon s3]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[image generation]]></category>
		<category><![CDATA[image hosting]]></category>
		<category><![CDATA[image storage]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[technical article]]></category>

		<guid isPermaLink="false">http://www.theartistsweb.net/news/2008/04/dos-and-donts-for-scaleable-image-hosting/</guid>
		<description><![CDATA[Top do's and don'ts from Chris Kirkland's experience in managing and hosting hundreds of thousands of images.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been reading my <a href="http://www.mrkirkland.com">web technology blog</a>, know what I&#8217;m up to or general stalking me in any other way then you&#8217;ll know I have been getting my hands dirty with <a href="http://www.theartistsweb.co.uk/">hosting artwork and photography images</a> for a number of years now. And from this experience I&#8217;ve decided to distill the following do&#8217;s and don&#8217;t list.</p>
<p>While this list is mainly geared towards high load situations, a lot of these points can easily be applied to sites of any scale, and you never know when your quite little blog is going to be hit by digg&#8230;</p>
<hr class="hr" />
<h3>Don&#8217;t serve images via application (i.e. php etc.)</h3>
<div class="highlight">The keyword here is <strong>serve</strong></div>
<p>I think it&#8217;s totally cool to use an <a href="http://phpthumb.sourceforge.net/">on the fly image generation script</a>, wanna tweak all the image sizes on your mega site by 1pixel, no problem: step 1) change a line in a config file step 2) no step 2! . In fact that&#8217;s the way I generally do things.</p>
<p>However there&#8217;s absolutely no reason why you should call this script more than one time per image. Yes I know you can handle caching in the script, but why bother? Write the images to disk and let your webserver do the dirty with caching etc. The way to do this is to &#8216;lazy load&#8217; this script i.e call the script once when the first time it is requested and the rest of the time the image file is served as normal &#8211; lazy load means your server doesn&#8217;t get clogged up for hours regenerating all your images, they are only regenerated when requested. Anyway this is simple enough todo with a 404 rule or Url rewriting:</p>
<p><strong>Diagram: Generate images with a script, but serve with apache (see tips below)</strong><br />
<a title="on the flyer image generation script" rel="attachment wp-att-855" href="http://www.theartistsweb.net/news/2008/04/dos-and-donts-for-scaleable-image-hosting/on-the-flyer-image-generation-script/"><img src="http://www.theartistsweb.net/news/wp-content/uploads/2008/04/on-the-fly-image-generation.jpg" alt="on the flyer image generation script" /></a></p>
<hr class="hr clear" />You can use a 404 script to send missing images, here&#8217;s how with a <a href="http://httpd.apache.org/docs/1.3/howto/htaccess.html">.htaccess file</a>:</p>
<pre class="code">ErrorDocument 404 /generate_image.php</pre>
<p>or an <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html"> apache url rewrite rule</a>:</p>
<pre class="code">RewriteCond $1 ^image
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /generate_image.php/$1 [L]</pre>
<p>Then in 404.php use the &#8216;REQUEST_URI&#8217; server variable to figure out what the image is &#8211; hopefully you have some sort of unique key in the file name e.g.<br />
/image/user/bob/23.jpg<br />
and call your image generation script , here&#8217;s a brief php example (based on the 404 redirect).</p>
<pre class="code">//what image is this
$url = $_SERVER['REQUEST_URI'];

$bits = explode('/',$url);

if($bits[0] == 'image' &amp;&amp; $bits[1] == 'user')
{
		$user = $bits[2];
		$image_id = $bits[2];
		generate_image_function($user,$image_id);

		//now redirect to the image etc.

}</pre>
<hr class="hr" />
<h3>Do use a <acronym title="Content Delivery Network">CDN</acronym></h3>
<div class="highlight">Scatter your seeds.</div>
<p>A <a href="http://developer.yahoo.com/performance/rules.html#cdn">content delivery network</a> helps speed up your page loads on many levels.</p>
<ul class="normalList">
<li>Images load faster if loaded from geographical near (to the user) server</li>
<li>Multiple server mean more images can load in parallel</li>
<li>It can free up resources on your application server (i.e. your website), as you can reduce the number of requests to the webserver, plus there&#8217;s no need to have a the webserver load all the bells and whislte your app needs (php modules etc.)</li>
</ul>
<h4>Poor Man&#8217;s <acronym title="Content Delivery Network">CDN </acronym></h4>
<p>A <acronym title="Content Delivery Network">CDN</acronym> sounds a bit scary and expensive, but if you simply move your images onto another server you&#8217;ll see a lot of the benefits already. As a simple poor man&#8217;s <acronym title="Content Delivery Network">CDN you could do the following:</acronym></p>
<ul class="normalList">
<li>Set up few domains for images &#8211; subdomains will do images-a.mysite.com images-b.mysite.com images-c.mysite.com</li>
<li>Get hold of one or more other webservers (bog standard webhosting accounts will do)</li>
<li>Use your app or round robin dns http://en.wikipedia.org/wiki/Round_robin_DNS to randomly prepend your domains to your image urls e.g.
<p>http://images-a.mysite.com/image/user/bob/97892789.jpg</li>
<li>Copy/<a href="http://samba.anu.edu.au/rsync/">rsync</a> your /image folder to the other server(s) with a cronjob</li>
<li>On the image servers have a 404/urlrewrite rule that sends the user back to the original server for images that aren&#8217;t yet copied across.<br />
.htaccess example:</p>
<pre class="code">RewriteCond $1 ^image
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://www.mysite.com/$1 [L]</pre>
</li>
</ul>
<p>This will work even if all the domains are on the same server (but different to your app) and aliasing to the same directory, plus it sets you up ready for exansion later when you really do need to break out onto multiple servers.</p>
<p><a title="Poor man’s content delivery network (for images)" rel="attachment wp-att-856" href="http://www.theartistsweb.net/news/2008/04/dos-and-donts-for-scaleable-image-hosting/poor-mans-content-delivery-network-for-images/"><img src="http://www.theartistsweb.net/news/wp-content/uploads/2008/04/poor-mans-cdn.jpg" alt="Poor man’s content delivery network (for images)" /></a></p>
<h4>Poor man&#8217;s <acronym title="Content Delivery Network">CDN plan B &#8211; Amazon S3</acronym></h4>
<p>Well this could perhaps be the plan A, as you&#8217;ll see in the point below S3 could act quite nicely as a CDN being a geographically dispersed set of redundant servers! I think my main concern would be the potential for the <a href="http://calculator.s3.amazonaws.com/calc5.html">bandwidth costs to rise</a>, they&#8217;ll be cheap enough to begin with, but it seems to me the cost scales closely with the bandwidth &#8211; if you compare 5TG monthly transfer: on S3 = $900 to dreamhost = included in basic plan.</p>
<hr class="hr clear" />
<h3>Do host data sources (precious original images) on a third party infinite disk</h3>
<div class="highlight">Multiple redundancy, infitite scalability, gourmet almond croissants</div>
<p>If you&#8217;ve got some funky image auto regeneration going on, or you simply want to store higher resolution &#8216;originals&#8217; then you&#8217;ll need a large warehouse and caretaker to look after then. Ideally multiple redundant replicated warehouses and caretakers in case one gets suicide bomber attacked etc.</p>
<p>When I started <a href="http://www.theartistsweb.co.uk">The Artists Web</a> I realised storage would be the first bottle neck I&#8217;d hit, so I quitely hoped the problem would just go away. In fact it did just go away because one day I discovered  <a href="http://aws.amazon.com/s3">Amazon S3</a>, moreover I read on  <a href="http://blogs.smugmug.com/don/2006/11/10/amazon-s3-show-me-the-money/">Don MacAskill&#8217;s blog</a> that his company switched over in about a day. So did we.</p>
<p>Amazon S3 is essentially an infinite network disk, I won&#8217;t go in to any technical details here but it&#8217;s cheap, easy to set up and spreads your data around the world in multiple redundant locations. There&#8217;s <a href="http://www.google.com/search?client=safari&amp;rls=ja-jp&amp;q=s3+library&amp;ie=UTF-8&amp;oe=UTF-8">plenty</a> of <a href="http://neurofuzzy.net/2006/03/17/amazon-s3-php-class/">libraries</a>, <a href="http://aws.amazon.com/s3">command line tools</a> and a few commercial services to boot.</p>
<hr class="hr" />
<h3>Don&#8217;t store images in a database</h3>
<div class="highlight">This is a japanese maintenance and back up horror film.</div>
<p>When I was planning a few years back, I remember reading forum threads debating whether it was a good idea to store images in a database. The reason I liked the idea of storing images in a database is centralization of data &#8211; no need to manage image back up separately. Arguments against seemed to be more about having to do your own caching, use of resources etc. However, you can out put cache headers from your scripts, write the (thumbnail) files to the file system etc. to get round all these performance issuses.</p>
<p>Nice as the central backup idea is, the problem (as I learned the not so easy way)  comes when you have more than a few hundred images &#8211; you have a Ghostbusters Marshmallow man crossed with a cow size database to back up. Even if you&#8217;re running backups off a replicated slave, your database is (most likely) many orders of magnitude larger than it needs to be which leads to all kinds of headaches. For instance disk space, restoring from backups or simply running a simple optimize table routine on a 100GB table is not my idea of a nice cron job (pun intended). And this feels somewhat like trying to swim with a pointless cow handcuffed to your ankle when the rest of your data is less than 48k (well, okay 480MB). There may be some reasons why &#8216;enterprise&#8217; databases (oracle?) don&#8217;t mind this kind of cow sitting inside them, but I only have experience of &#8216;toy&#8217; databases like <a href="http://www.mysql.com/">mysql</a>.</p>
<p><strong>Don&#8217;t store your images in your database kids.</strong></p>
<hr class="hr" />
<h3>Do use a class/function to get image urls</h3>
<div class="highlight">Save headaches later on.</div>
<p>Your image url schema is probably simple, something like : /images/username/size_imageid_imagename.jpg. So is it really worth having a function/class to generate urls? Well it&#8217;s certainly not going to hurt and is going to save time later on: want to shift to a <acronym title="Content Delivery Network">CDN? substitute smaller images for mobile devices? serve the image from a different server depending on geographic location of the user?, no problem, most of these could be done with a few lines of code added to the image url class.</acronym></p>
<pre class="code">//normal images
$image_url-&gt;get_image_url($image_id);
$image_url-&gt;get_user_avatar($user_id);

//mobile devices? piece of cake
$image_url-&gt;set_mobile_device();
$image_url-&gt;get_image_url($image_id); //returns url to smaller image size
$image_url-&gt;get_user_avatar($user_id); //ditto</pre>
<hr class="hr" />
<h3>Do use a config file for image sizes</h3>
<p>If you&#8217;re following the above rule, then you&#8217;ll probably be doing this anyway:</p>
<pre class="code">class image_url ()
{
		var $tiny_thumbnail_size = 30;
		var $thumbnail_size = 200;
		var $image_size = 400;

		/* etc. */

}</pre>
<p>Simply make sure you only need to specify your images sizes in one place.</p>
<h3>That&#8217;s it (for now)</h3>
<p>Well I&#8217;m sure I&#8217;ll be back to add some more points, in the meantime hope you find this a useful read and look forward to your feedback!</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-caring-old">
<ul class="socials">
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Do%27s+and+Dont%27s+for+scaleable+image+hosting+-+File: /data/app/webapp/functions.php<br />Line: 7<br />Message: Too many connections&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/&amp;t=Do%27s+and+Dont%27s+for+scaleable+image+hosting" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-comfeed">
			<a href="http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/&amp;title=Do%27s+and+Dont%27s+for+scaleable+image+hosting" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-digg">
			<a href="http://digg.com/submit?phase=2&amp;url=http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/&amp;title=Do%27s+and+Dont%27s+for+scaleable+image+hosting" rel="nofollow" class="external" title="Digg this!">Digg this!</a>
		</li>
		<li class="shr-reddit">
			<a href="http://reddit.com/submit?url=http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/&amp;title=Do%27s+and+Dont%27s+for+scaleable+image+hosting" rel="nofollow" class="external" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/&amp;title=Do%27s+and+Dont%27s+for+scaleable+image+hosting" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-technorati">
			<a href="http://technorati.com/faves?add=http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/" rel="nofollow" class="external" title="Share this on Technorati">Share this on Technorati</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://blog.artweb.com/2008/04/dos-and-donts-for-scaleable-image-hosting/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)
Object Caching 213/233 objects using disk

Served from: blog.artweb.com @ 2012-02-10 02:42:44 -->
