<?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>PlanetMysql.ru - информация о СУБД MySQL &#187; networks</title>
	<atom:link href="http://planetmysql.ru/category/networks/feed/" rel="self" type="application/rss+xml" />
	<link>http://planetmysql.ru</link>
	<description>Блог о самой популярной СУБД MySQL</description>
	<lastBuildDate>Thu, 24 May 2012 22:24:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Scribd is Hiring (I’m Looking for an Operations Engineer to Join My Team)</title>
		<link>http://feedproxy.google.com/~r/Homo-Adminus/~3/PqbAzRHL-mg/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scribd-is-hiring-i%25e2%2580%2599m-looking-for-an-operations-engineer-to-join-my-team</link>
		<comments>http://feedproxy.google.com/~r/Homo-Adminus/~3/PqbAzRHL-mg/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 15:51:06 +0000</pubDate>
		<dc:creator>Alexey Kovyrin</dc:creator>
				<category><![CDATA[admin]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[Operations]]></category>
		<category><![CDATA[scribd]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://kovyrin.net/?p=502</guid>
		<description><![CDATA[Scribd is a top 100 site on the web and one of the largest sites built using Ruby on Rails. As one of the first rails sites to reach scale, we&#8217;ve built a lot of infrastructure and solved a lot of challenges to get Scribd to where it is today. We actively try to push the envelope and have contributed substantial work back to the open source community.
Scribd has an agile, startup culture and an unusually close working relationship between engineering and ops. You&#8217;ll regularly find cross-over work at Scribd, with ops people writing application-layer code and engineers figuring out operations-level problems. We think we&#8217;re able to make that work because of the uniquely talented people we have on the team.
To allow us to keep scaling, we&#8217;re now looking to add a strong, experienced operations guru to the team. As a member of Scribd operations, you&#8217;ll have tremendous ownership and responsibility for one of the web&#8217;s most popular applications. Because Scribd is a startup, you will wear many hats and have broader responsibility than you would at a larger company.
If you read this blog, you should already have a good sense of the kind of work you&#8217;ll be doing on this position. 
The Ideal Profile
You are an experienced operations professional and have run ops at at least one large-scale website. You have comprehensive knowledge of a broad variety of system tools, from MySQL and Nginx to Squid and Memcached. You should also have strong software development skills and be well-versed in major programming languages. You should be strongly motivated, a creative solution finder, and ready to jump into the thorniest technical problems whenever necessary.
 Responsibilities

Develop and maintain all aspects of Scribd&#8217;s operations infrastructure, including system monitoring, backups, server configuration, databases, and caching systems
Collaborate with engineering to create next generation infrastructure to support changing requirements
Predict scaling problems before they occur and work with engineering to prevent them
Write and debug application level ruby code
Participate in an on-call rotation
Quickly diagnose server problems and employ preventive measures to maintain high availability servers

Qualifications

Bachelors degree in CS or equivalent experience
3-5 years of professional experience in site operations
Strong software engineering skills, including knowledge of major programming languages
Strong database skills, preferably with MySQL, and overall linux knowledge
Experience with most of the following technologies: MySQL, Nginx, Ruby, Memcached, Squid, git, Solr, HBase, Postfix
Proven ability to quickly learn and implement unfamiliar technologies
Strong desire to work hard at a rapidly growing company

Location: You are preferably located near San Francisco, CA. Relocation assistance is designed on a per-case basis. In short, we&#8217;ll be creative to get you here.
Contact: Please send your email cover letter and resume with the subject &#8220;Your name – Senior Site Operations Engineer – via Kovyrin.net&#8221; to jobs@scribd.com or contact me directly using any of my contacts. All communication and correspondence is held in the strictest confidence to ensure that you can connect and learn more without exposure.



  
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.scribd.com/">Scribd</a> is a <a href="http://rails100.pbworks.com/Alexa+Rankings">top 100 site</a> on the web and one of the largest sites built using Ruby on Rails. As one of the first rails sites to reach scale, we&#8217;ve built a lot of infrastructure and solved a lot of challenges to get Scribd to where it is today. We actively try to push the envelope and have contributed substantial work back to the open source community.</p>
<p>Scribd has an agile, startup culture and an unusually close working relationship between engineering and ops. You&#8217;ll regularly find cross-over work at Scribd, with ops people writing application-layer code and engineers figuring out operations-level problems. We think we&#8217;re able to make that work because of the uniquely talented people we have on the team.</p>
<p>To allow us to keep scaling, we&#8217;re now looking to add a strong, experienced operations guru to the team. As a member of Scribd operations, you&#8217;ll have tremendous ownership and responsibility for one of the web&#8217;s most popular applications. Because Scribd is a startup, you will wear many hats and have broader responsibility than you would at a larger company.</p>
<p>If you read this blog, you should already have a good sense of the kind of work you&#8217;ll be doing on this position. </p>
<p><strong>The Ideal Profile</strong></p>
<p>You are an experienced operations professional and have run ops at at least one large-scale website. You have comprehensive knowledge of a broad variety of system tools, from MySQL and Nginx to Squid and Memcached. You should also have strong software development skills and be well-versed in major programming languages. You should be strongly motivated, a creative solution finder, and ready to jump into the thorniest technical problems whenever necessary.</p>
<p><strong> Responsibilities</strong></p>
<ul>
<li>Develop and maintain all aspects of Scribd&#8217;s operations infrastructure, including system monitoring, backups, server configuration, databases, and caching systems</li>
<li>Collaborate with engineering to create next generation infrastructure to support changing requirements</li>
<li>Predict scaling problems before they occur and work with engineering to prevent them</li>
<li>Write and debug application level ruby code</li>
<li>Participate in an on-call rotation</li>
<li>Quickly diagnose server problems and employ preventive measures to maintain high availability servers</li>
</ul>
<p><strong>Qualifications</strong></p>
<ul>
<li>Bachelors degree in CS or equivalent experience</li>
<li>3-5 years of professional experience in site operations</li>
<li>Strong software engineering skills, including knowledge of major programming languages</li>
<li>Strong database skills, preferably with MySQL, and overall linux knowledge</li>
<li>Experience with most of the following technologies: MySQL, Nginx, Ruby, Memcached, Squid, git, Solr, HBase, Postfix</li>
<li>Proven ability to quickly learn and implement unfamiliar technologies</li>
<li>Strong desire to work hard at a rapidly growing company</li>
</ul>
<p>Location: <strong>You are preferably located near San Francisco, CA</strong>. Relocation assistance is designed on a per-case basis. In short, we&#8217;ll be creative to get you here.</p>
<p>Contact: Please send your email cover letter and resume with the subject &#8220;Your name – Senior Site Operations Engineer – via Kovyrin.net&#8221; to jobs@scribd.com or contact me directly using <a href="http://kovyrin.net/contact/">any of my contacts</a>. All communication and correspondence is held in the strictest confidence to ensure that you can connect and learn more without exposure.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/RWGCGmnRKReW6byQK16_MflmLOE/0/da"><img src="http://feedads.g.doubleclick.net/~a/RWGCGmnRKReW6byQK16_MflmLOE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/RWGCGmnRKReW6byQK16_MflmLOE/1/da"><img src="http://feedads.g.doubleclick.net/~a/RWGCGmnRKReW6byQK16_MflmLOE/1/di" border="0" ismap="true"></img></a></p><div>
<a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=PqbAzRHL-mg:y4-nncz8nKI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=PqbAzRHL-mg:y4-nncz8nKI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=PqbAzRHL-mg:y4-nncz8nKI:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=PqbAzRHL-mg:y4-nncz8nKI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=PqbAzRHL-mg:y4-nncz8nKI:V_sGLiPBpWU" border="0"></img></a>
</div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=25576&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=25576&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2010/08/17/scribd-is-hiring-i%e2%80%99m-looking-for-an-operations-engineer-to-join-my-team/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nginx-Fu: X-Accel-Redirect From Remote Servers</title>
		<link>http://feedproxy.google.com/~r/Homo-Adminus/~3/cuG-f1auDlo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=nginx-fu-x-accel-redirect-from-remote-servers</link>
		<comments>http://feedproxy.google.com/~r/Homo-Adminus/~3/cuG-f1auDlo/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 03:45:52 +0000</pubDate>
		<dc:creator>Alexey Kovyrin</dc:creator>
				<category><![CDATA[Admin-tips]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[nginx-fu]]></category>
		<category><![CDATA[redirect]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[x-accel-redirect]]></category>

		<guid isPermaLink="false">http://kovyrin.net/?p=462</guid>
		<description><![CDATA[We use nginx and its features a lot in Scribd. Many times in the last year we needed some pretty interesting, but not supported feature &#8211; we wanted nginx X-Accel-Redirect functionality to work with remote URLs. Our of the box nginx supports this functionality for local URIs only. In this short post I want to explain how did we make nginx serve remote content via X-Accel-Redirect.

First of all, here is what you may need this feature. Let&#8217;s imagine you have a file storage on Amazon S3 where you store tons of content. And you have an application where you have some content downloading functionality that you want to be available for logged-in/paying/premium users and/or you want to keep track of downloads your users perform on your site. If your content was on your web server, you could have used simple controlled downloads functionality built-in to nginx out of the box. But the problem is that your content is remote.
Here is what we do to solve this problem.
First, we create a special location on our nginx server. This location will be used as a proxy for all our accelerated file downloads:
1234567891011121314151617181920212223242526272829303132333435# Proxy download 
location ~* ^/internal_redirect/&#40;.*?&#41;/&#40;.*&#41; &#123;
&#160; &#160; # Do not allow people to mess with this location directly
&#160; &#160; # Only internal redirects are allowed
&#160; &#160; internal;

&#160; &#160; # Location-specific logging
&#160; &#160; access_log logs/internal_redirect.access.log main;
&#160; &#160; error_log logs/internal_redirect.error.log warn;

&#160; &#160; # Extract download url from the request
&#160; &#160; set $download_uri $2;
&#160; &#160; set $download_host $1;

&#160; &#160; # Compose download url
&#160; &#160; set $download_url http://$download_host/$download_uri;

&#160; &#160; # Set download request headers
&#160; &#160; proxy_set_header Host $download_host;
&#160; &#160; proxy_set_header Authorization '';

&#160; &#160; # The next two lines could be used if your storage 
&#160; &#160; # backend does not support Content-Disposition 
&#160; &#160; # headers used to specify file name browsers use 
&#160; &#160; # when save content to the disk
&#160; &#160; proxy_hide_header Content-Disposition;
&#160; &#160; add_header Content-Disposition 'attachment; filename=&#34;$args&#34;';

&#160; &#160; # Do not touch local disks when proxying 
&#160; &#160; # content to clients
&#160; &#160; proxy_max_temp_file_size 0;

&#160; &#160; # Download the file and send it to client
&#160; &#160; proxy_pass $download_url;
&#125;
After adding this location to our nginx config we could start sending responses with headers like the following:
1234567# This header will ask nginx to download a file 
# from http://some.site.com/secret/url.ext and send it to user
X-Accel-Redirect: /internal_redirect/some.site.com/secret/url.ext

# This header will ask nginx to download a file 
# from http://blah.com/secret/url and send it to user as cool.pdf
X-Accel-Redirect: /internal_redirect/blah.com/secret/url?cool.pdf
Here is an example code you could use in a Rails application to use our internal redirect location:
12345678910def x_accel_url&#40;url, file_name = nil&#41;
&#160; uri = &#34;/internal_redirect/#{url.gsub('http://', '')}&#34;
&#160; uri &#60;&#60; &#34;?#{file_name}&#34; if file_name
&#160; return uri
end

def download
&#160; headers&#91;'X-Accel-Redirect'&#93; = x_accel_url&#40;some_secret_url, pretty_name&#41;
&#160; render :nothing =&#62; true
end
As you can see, nginx is really powerful tool and when you turn your creativity on you can make it even more powerful. Stay tuned for more Nginx-Fu posts.



  
]]></description>
			<content:encoded><![CDATA[<p>We use <a href="http://nginx.org/">nginx</a> and its features a lot in <a href="http://www.scribd.com/">Scribd</a>. Many times in the last year we needed some pretty interesting, but not supported feature &#8211; we wanted nginx <a href="http://wiki.nginx.org/NginxXSendfile"><tt>X-Accel-Redirect</tt></a> functionality to work with remote URLs. Our of the box nginx supports this functionality for local URIs only. In this short post I want to explain how did we make nginx serve remote content via <nobr><tt>X-Accel-Redirect</tt></nobr>.</p>
<p><span></span></p>
<p>First of all, here is what you may need this feature. Let&#8217;s imagine you have a file storage on <a href="http://aws.amazon.com/s3/">Amazon S3</a> where you store tons of content. And you have an application where you have some content downloading functionality that you want to be available for logged-in/paying/premium users and/or you want to keep track of downloads your users perform on your site. If your content was on your web server, you could have used simple <a href="http://kovyrin.net/2006/11/01/nginx-x-accel-redirect-php-rails/">controlled downloads</a> functionality built-in to nginx out of the box. But the problem is that your content is remote.</p>
<p>Here is what we do to solve this problem.</p>
<p>First, we create a special location on our nginx server. This location will be used as a proxy for all our accelerated file downloads:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br /></div></td><td><div><span># Proxy download </span><br />
<span>location</span> ~* ^/internal_redirect/<span>&#40;</span>.*?<span>&#41;</span>/<span>&#40;</span>.*<span>&#41;</span> <span>&#123;</span><br />
&nbsp; &nbsp; <span># Do not allow people to mess with this location directly</span><br />
&nbsp; &nbsp; <span># Only internal redirects are allowed</span><br />
&nbsp; &nbsp; <span>internal</span>;<br />
<br />
&nbsp; &nbsp; <span># Location-specific logging</span><br />
&nbsp; &nbsp; <span>access_log</span> logs/internal_redirect.access.log main;<br />
&nbsp; &nbsp; <span>error_log</span> logs/internal_redirect.error.log warn;<br />
<br />
&nbsp; &nbsp; <span># Extract download url from the request</span><br />
&nbsp; &nbsp; set <span>$download_uri</span> <span>$2</span>;<br />
&nbsp; &nbsp; set <span>$download_host</span> <span>$1</span>;<br />
<br />
&nbsp; &nbsp; <span># Compose download url</span><br />
&nbsp; &nbsp; set <span>$download_url</span> <span>http</span>://<span>$download_host</span>/<span>$download_uri</span>;<br />
<br />
&nbsp; &nbsp; <span># Set download request headers</span><br />
&nbsp; &nbsp; <span>proxy_set_header</span> <span>Host</span> <span>$download_host</span>;<br />
&nbsp; &nbsp; <span>proxy_set_header</span> Authorization <span>''</span>;<br />
<br />
&nbsp; &nbsp; <span># The next two lines could be used if your storage </span><br />
&nbsp; &nbsp; <span># backend does not support Content-Disposition </span><br />
&nbsp; &nbsp; <span># headers used to specify file name browsers use </span><br />
&nbsp; &nbsp; <span># when save content to the disk</span><br />
&nbsp; &nbsp; proxy_hide_header Content-Disposition;<br />
&nbsp; &nbsp; add_header Content-Disposition <span>'attachment; filename=&quot;$args&quot;'</span>;<br />
<br />
&nbsp; &nbsp; <span># Do not touch local disks when proxying </span><br />
&nbsp; &nbsp; <span># content to clients</span><br />
&nbsp; &nbsp; proxy_max_temp_file_size <span>0</span>;<br />
<br />
&nbsp; &nbsp; <span># Download the file and send it to client</span><br />
&nbsp; &nbsp; <span>proxy_pass</span> <span>$download_url</span>;<br />
<span>&#125;</span></div></td></tr></tbody></table></div>
<p>After adding this location to our nginx config we could start sending responses with headers like the following:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div><span># This header will ask nginx to download a file </span><br />
<span># from http://some.site.com/secret/url.ext and send it to user</span><br />
X-Accel-Redirect: /internal_redirect/some.site.com/secret/url.ext<br />
<br />
<span># This header will ask nginx to download a file </span><br />
<span># from http://blah.com/secret/url and send it to user as cool.pdf</span><br />
X-Accel-Redirect: /internal_redirect/blah.com/secret/url?cool.pdf</div></td></tr></tbody></table></div>
<p>Here is an example code you could use in a Rails application to use our internal redirect location:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div><span>def</span> x_accel_url<span>&#40;</span>url, file_name = <span>nil</span><span>&#41;</span><br />
&nbsp; uri = <span>&quot;/internal_redirect/#{url.gsub('http://', '')}&quot;</span><br />
&nbsp; uri <span>&lt;&lt;</span> <span>&quot;?#{file_name}&quot;</span> <span>if</span> file_name<br />
&nbsp; <span>return</span> uri<br />
<span>end</span><br />
<br />
<span>def</span> download<br />
&nbsp; headers<span>&#91;</span><span>'X-Accel-Redirect'</span><span>&#93;</span> = x_accel_url<span>&#40;</span>some_secret_url, pretty_name<span>&#41;</span><br />
&nbsp; render <span>:nothing</span> <span>=&gt;</span> <span>true</span><br />
<span>end</span></div></td></tr></tbody></table></div>
<p>As you can see, nginx is really powerful tool and when you turn your creativity on you can make it even more powerful. Stay tuned for more <a href="http://kovyrin.net/tag/nginx-fu/">Nginx-Fu</a> posts.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/s4KHA4LgENGAamK4PL09U7Ia3f8/0/da"><img src="http://feedads.g.doubleclick.net/~a/s4KHA4LgENGAamK4PL09U7Ia3f8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/s4KHA4LgENGAamK4PL09U7Ia3f8/1/da"><img src="http://feedads.g.doubleclick.net/~a/s4KHA4LgENGAamK4PL09U7Ia3f8/1/di" border="0" ismap="true"></img></a></p><div>
<a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=cuG-f1auDlo:LUrpmTqfO4k:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=cuG-f1auDlo:LUrpmTqfO4k:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=cuG-f1auDlo:LUrpmTqfO4k:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=cuG-f1auDlo:LUrpmTqfO4k:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=cuG-f1auDlo:LUrpmTqfO4k:V_sGLiPBpWU" border="0"></img></a>
</div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=25095&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=25095&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2010/06/24/nginx-fu-x-accel-redirect-from-remote-servers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced Squid Caching in Scribd: Cache Invalidation Techniques</title>
		<link>http://feedproxy.google.com/~r/Homo-Adminus/~3/4ywVA01ppFY/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=advanced-squid-caching-in-scribd-cache-invalidation-techniques</link>
		<comments>http://feedproxy.google.com/~r/Homo-Adminus/~3/4ywVA01ppFY/#comments</comments>
		<pubDate>Sat, 29 May 2010 17:02:17 +0000</pubDate>
		<dc:creator>Alexey Kovyrin</dc:creator>
				<category><![CDATA[Admin-tips]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[HTCP]]></category>
		<category><![CDATA[invalidation]]></category>
		<category><![CDATA[My Projects]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[squid]]></category>

		<guid isPermaLink="false">http://kovyrin.net/?p=322</guid>
		<description><![CDATA[Having a reverse-proxy web cache as one of the major infrastructure elements brings many benefits for large web applications: it reduces your application servers load, reduces average response times on your site, etc. But there is one problem every developer experiences when works with such a cache &#8211; cached content invalidation.
It is a complex problem that usually consists of two smaller ones: individual cache elements invalidation (you need to keep an eye on your data changes and invalidate cached pages when related data changes) and full cache purges (sometimes your site layout or page templates change and you need to purge all the cached pages to make sure users will get new visual elements of layout changes). In this post I&#8217;d like to look at a few techniques we use at Scribd to solve cache invalidation problems.

So, the first problem &#8211; ongoing cache invalidation when content changes. This is actually a pretty simple task in squid: you just use HTCP protocol and send CLR requests to your caching farm (we didn&#8217;t find any HTCP protocol implementations so we&#8217;ve implemented our own simple client that supports just one command).
Since we use haproxy to balance our traffic in the cluster it is hard to predict where should we send a purge request. So we fan those out to all cache servers.
To make sure cache purging won&#8217;t slow the site down, especially considering we need to do more that just a simple cache purge (submit documents to search indexes, etc, etc), we just spool a &#8220;document changed&#8221; request to a queue and then have a set of asynchronous processes that do all the work in background.
Next, The Hard Problem &#8211; handling full cache purges w/o killing our backend servers with 5x-10x traffic (our normal hit ratio is ~90-95%).
We&#8217;ve spent a lot of time thinking about this problem and the first idea we came up with was to have a loop process somewhere that would iterate all documents we have cached and purge them one by one&#8230; but that does not seem to be a practical solution when you have tens of millions documents (and few page versions per document) and obviously the solution would not scale with constantly growing documents corpus.
So we kept brainstorming and finally got one idea that works just perfectly for us: what if we&#8217;d be able to take our traffic and define a function f(t) that would return a percentage of the traffic that should be purged at any moment in time. So we did it &#8211; we&#8217;ve implemented a nginx module that would version our cache by assigning every cached page a revision (using a custom HTTP-headers + Vary-caching) and would be able to slowly migrate the cache from one revision to another over a pre-defined period of time.
Having that module we are able to do so called &#8220;slow&#8221; cache purges that could take any time from a few minutes (that still helps to reduce the load spike generated by the hottest content) up to many hours (this is what we normally use) or days (never used this option, but it is definitely possible).
Here is an example 100% cache purge over an 8 hour interval:

 Daily hit ratio graph:


 Weekly hit ratio graph:



As you can see, during those slow purges our cached pages would be slowly updated without putting too much pressure on the backend. Cache hit ratio would slowly degrade and then slowly get back to its normal levels, but with our normal (6-8 hours) purges hit ratio never gets lower that 65-70% which makes it possible for us to save huge amounts of money on not having 90% spare capacity just for the cache purge load surges (we used to have lots of spare application cluster capacity before introducing this approach).



  
]]></description>
			<content:encoded><![CDATA[<p>Having a <a href="http://kovyrin.net/2008/10/25/advanced-squid-caching-for-rails-applications-preface/">reverse-proxy</a> web cache as one of the major infrastructure elements brings many benefits for large web applications: it reduces your application servers load, reduces average response times on your site, etc. But there is one problem every developer experiences when works with such a cache &#8211; <em>cached content invalidation</em>.</p>
<p>It is a complex problem that usually consists of two smaller ones: i<em>ndividual cache elements invalidation</em> (you need to keep an eye on your data changes and invalidate cached pages when related data changes) and <em>full cache purges</em> (sometimes your site layout or page templates change and you need to purge all the cached pages to make sure users will get new visual elements of layout changes). In this post I&#8217;d like to look at a few techniques we use at <a href="http://www.scribd.com/">Scribd</a> to solve cache invalidation problems.</p>
<p><span></span></p>
<hr />So, the <strong>first problem &#8211; ongoing cache invalidation when content changes</strong>. This is actually a pretty simple task in squid: you just use <a href="http://www.htcp.org/">HTCP protocol</a> and send CLR requests to your caching farm (we didn&#8217;t find any HTCP protocol implementations so we&#8217;ve implemented <a href="http://github.com/kovyrin/htcp-ruby">our own simple client</a> that supports just one command).</p>
<p>Since we use <a href="http://haproxy.1wt.eu/">haproxy</a> to balance our traffic in the cluster it is hard to predict where should we send a purge request. So we fan those out to all cache servers.</p>
<p>To make sure cache purging won&#8217;t slow the site down, especially considering we need to do more that just a simple cache purge (submit documents to search indexes, etc, etc), we just spool a &#8220;document changed&#8221; request to a queue and then have a set of <a href="http://github.com/kovyrin/loops">asynchronous processes</a> that do all the work in background.</p>
<p>Next, <strong>The Hard Problem &#8211; handling full cache purges w/o killing our backend servers</strong> with 5x-10x traffic (our normal hit ratio is ~90-95%).</p>
<p>We&#8217;ve spent a lot of time thinking about this problem and the first idea we came up with was to have a loop process somewhere that would iterate all documents we have cached and purge them one by one&#8230; but that does not seem to be a practical solution when you have tens of millions documents (and few page versions per document) and obviously the solution would not scale with constantly growing documents corpus.</p>
<p>So we kept brainstorming and finally got one idea that works just perfectly for us: what if we&#8217;d be able to take our traffic and define a function <em>f(t)</em> that would return a percentage of the traffic that should be purged at any moment in time. So we did it &#8211; we&#8217;ve implemented a nginx module that would version our cache by assigning every cached page a revision (<a href="http://kovyrin.net/2009/07/21/advanced-squid-caching-scribd-logged-in-users-complex-urls/">using a custom HTTP-headers + Vary-caching</a>) and would be able to slowly migrate the cache from one revision to another over a pre-defined period of time.</p>
<p>Having that module we are able to do so called &#8220;slow&#8221; cache purges that could take any time from a few minutes (that still helps to reduce the load spike generated by the hottest content) up to many hours (this is what we normally use) or days (never used this option, but it is definitely possible).</p>
<p>Here is an example 100% cache purge over an 8 hour interval:</p>
<ol>
<li> Daily hit ratio graph:<br />
<a href="http://img.skitch.com/20100529-pkx64g6the9winqcnk6sigiyns.png" rel="shadowbox[post-322];player=img;"><img rel="shadowbox" src="http://img.skitch.com/20100529-pkx64g6the9winqcnk6sigiyns.preview.jpg" alt="day" /></a>
</li>
<li> Weekly hit ratio graph:<br />
<a href="http://img.skitch.com/20100529-nk2hyafgtbw1pc1nrkgbec8st3.png" rel="shadowbox[post-322];player=img;"><img rel="shadowbox" src="http://img.skitch.com/20100529-nk2hyafgtbw1pc1nrkgbec8st3.preview.jpg" alt="week" /></a>
</li>
</ol>
<p>As you can see, during those slow purges our cached pages would be slowly updated without putting too much pressure on the backend. Cache hit ratio would slowly degrade and then slowly get back to its normal levels, but with our normal (6-8 hours) purges hit ratio never gets lower that 65-70% which makes it possible for us to save huge amounts of money on not having 90% spare capacity just for the cache purge load surges (we used to have lots of spare application cluster capacity before introducing this approach).</p>

<p><a href="http://feedads.g.doubleclick.net/~a/-nlVyidsWJg1e-DbtPeODrcR9bY/0/da"><img src="http://feedads.g.doubleclick.net/~a/-nlVyidsWJg1e-DbtPeODrcR9bY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/-nlVyidsWJg1e-DbtPeODrcR9bY/1/da"><img src="http://feedads.g.doubleclick.net/~a/-nlVyidsWJg1e-DbtPeODrcR9bY/1/di" border="0" ismap="true"></img></a></p><div>
<a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=4ywVA01ppFY:b2ode2vaNL0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=4ywVA01ppFY:b2ode2vaNL0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=4ywVA01ppFY:b2ode2vaNL0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=4ywVA01ppFY:b2ode2vaNL0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=4ywVA01ppFY:b2ode2vaNL0:V_sGLiPBpWU" border="0"></img></a>
</div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=24897&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=24897&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2010/05/29/advanced-squid-caching-in-scribd-cache-invalidation-techniques/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enabling IPv6 Support in nginx</title>
		<link>http://feedproxy.google.com/~r/Homo-Adminus/~3/TpJuKctpPjk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enabling-ipv6-support-in-nginx</link>
		<comments>http://feedproxy.google.com/~r/Homo-Adminus/~3/TpJuKctpPjk/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 09:39:44 +0000</pubDate>
		<dc:creator>Alexey Kovyrin</dc:creator>
				<category><![CDATA[admin]]></category>
		<category><![CDATA[Admin-tips]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[ipv6]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://kovyrin.net/?p=362</guid>
		<description><![CDATA[This is going to be a really short post, but for someone it could save an hour of life.
So, you&#8217;ve nothing to do and you&#8217;ve decided to play around with IPv6 or maybe you&#8217;re happened to be an administrator of a web service that needs to support IPv6 connectivity and you need to make your nginx server work nicely with this protocol. 
First thing you need to do is to enable IPv6 in nginx by recompiling it with --with-ipv6 configure option and reinstalling it. If you use some pre-built package, check if your nginx already has this key enabled by running nginx -V. 

The results should have --with-ipv6 option in configure arguments:
12345[root@node ~]# nginx -V
nginx version: nginx/0.7.64
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-46)
TLS SNI support disabled
configure arguments: --with-ipv6 ... --prefix=/opt/nginx
After you&#8217;ve got your nginx binary with IPv6 support, you need to enable it by changing listen directives in your configuration file. 
If your server binds to all interfaces/IPs, you already have listen 80 or something like that in your file. Those lines should be changed to make sure you tell your nginx to bind on both IPv4 and IPv6 addresses:
1listen [::]:80;
For situations when you do not want to listen on IPv4 interfaces, there is ipv6only=on parameter:
1listen [::]:443 default ipv6only=on;
For configurations that need to bind to specific ip addresses you could use similar notation:
1listen [2607:f0d0:1004:2::2]:80;
After changing your configs and testing them you need to restart (not reload) your nginx process and then check your system port bindings to make sure it works as expected:
123[root@node ~]# netstat -nlp &#124; grep nginx
tcp &#160; 0 &#160; &#160;0 :::80 &#160; &#160; &#160; &#160;:::* &#160; &#160; &#160; &#160; LISTEN &#160; &#160;23817/nginx
tcp &#160; 0 &#160; &#160;0 :::443 &#160; &#160; &#160; :::* &#160; &#160; &#160; &#160; LISTEN &#160; &#160;23817/nginx
This is it, now you can add AAAA records to your main domain name or just create a dedicated ipv6.yourcompany.com sub-domain and show it to your friends  



  
]]></description>
			<content:encoded><![CDATA[<p>This is going to be a really short post, but for someone it could save an hour of life.</p>
<p>So, you&#8217;ve nothing to do and you&#8217;ve decided to play around with <a href="http://en.wikipedia.org/wiki/IPv6">IPv6</a> or maybe you&#8217;re happened to be an administrator of a web service that needs to support IPv6 connectivity and you need to make your <a href="http://nginx.org/">nginx</a> server work nicely with this protocol. </p>
<p>First thing you need to do is to enable IPv6 in nginx by recompiling it with <code><span>--with-ipv6</span></code> configure option and reinstalling it. If you use some pre-built package, check if your nginx already has this key enabled by running <code><span>nginx -V</span></code>. </p>
<p><span></span></p>
<p>The results should have <code><span>--with-ipv6</span></code> option in configure arguments:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div>[root@node ~]# nginx -V<br />
nginx version: nginx/0.7.64<br />
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-46)<br />
TLS SNI support disabled<br />
configure arguments: --with-ipv6 ... --prefix=/opt/nginx</div></td></tr></tbody></table></div>
<p>After you&#8217;ve got your nginx binary with IPv6 support, you need to enable it by changing <code><span>listen</span></code> directives in your configuration file. </p>
<p>If your server binds to all interfaces/IPs, you already have <code><span>listen 80</span></code> or something like that in your file. Those lines should be changed to make sure you tell your nginx to bind on both IPv4 and IPv6 addresses:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br /></div></td><td><div>listen [::]:80;</div></td></tr></tbody></table></div>
<p>For situations when you do not want to listen on IPv4 interfaces, there is <code><span>ipv6only=on</span></code> parameter:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br /></div></td><td><div>listen [::]:443 default ipv6only=on;</div></td></tr></tbody></table></div>
<p>For configurations that need to bind to specific ip addresses you could use similar notation:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br /></div></td><td><div>listen [2607:f0d0:1004:2::2]:80;</div></td></tr></tbody></table></div>
<p>After changing your configs and testing them you need to restart (not reload) your nginx process and then check your system port bindings to make sure it works as expected:</p>
<div><table cellspacing="0" cellpadding="0"><tbody><tr><td><div>1<br />2<br />3<br /></div></td><td><div>[root@node ~]# netstat -nlp | grep nginx<br />
tcp &nbsp; 0 &nbsp; &nbsp;0 :::80 &nbsp; &nbsp; &nbsp; &nbsp;:::* &nbsp; &nbsp; &nbsp; &nbsp; LISTEN &nbsp; &nbsp;23817/nginx<br />
tcp &nbsp; 0 &nbsp; &nbsp;0 :::443 &nbsp; &nbsp; &nbsp; :::* &nbsp; &nbsp; &nbsp; &nbsp; LISTEN &nbsp; &nbsp;23817/nginx</div></td></tr></tbody></table></div>
<p>This is it, now you can add <a href="http://en.wikipedia.org/wiki/IPv6_Addresses#IPv6_addresses_in_the_Domain_Name_System">AAAA</a> records to your main domain name or just create a dedicated <a href="http://ipv6.scribd.com">ipv6</a>.<a href="http://ipv6.google.com">yourcompany</a>.<a href="http://ipv6.netflix.com">com</a> sub-domain and show it to your friends <img src="http://kovyrin.net/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley" /> </p>

<p><a href="http://feedads.g.doubleclick.net/~a/sJSdXloba3FdnnOJmBMpY3OC5U0/0/da"><img src="http://feedads.g.doubleclick.net/~a/sJSdXloba3FdnnOJmBMpY3OC5U0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/sJSdXloba3FdnnOJmBMpY3OC5U0/1/da"><img src="http://feedads.g.doubleclick.net/~a/sJSdXloba3FdnnOJmBMpY3OC5U0/1/di" border="0" ismap="true"></img></a></p><div>
<a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=TpJuKctpPjk:Yc3Q-fyY3Vw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=TpJuKctpPjk:Yc3Q-fyY3Vw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=TpJuKctpPjk:Yc3Q-fyY3Vw:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=TpJuKctpPjk:Yc3Q-fyY3Vw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=TpJuKctpPjk:Yc3Q-fyY3Vw:V_sGLiPBpWU" border="0"></img></a>
</div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23077&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23077&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2010/01/16/enabling-ipv6-support-in-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced Squid Caching in Scribd: Hardware + Software Used</title>
		<link>http://feedproxy.google.com/~r/Homo-Adminus/~3/s8GVmmmES8s/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=advanced-squid-caching-in-scribd-hardware-software-used</link>
		<comments>http://feedproxy.google.com/~r/Homo-Adminus/~3/s8GVmmmES8s/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 05:23:18 +0000</pubDate>
		<dc:creator>Alexey Kovyrin</dc:creator>
				<category><![CDATA[Admin-tips]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[haproxy]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[scribd]]></category>
		<category><![CDATA[squid]]></category>

		<guid isPermaLink="false">http://kovyrin.net/?p=298</guid>
		<description><![CDATA[After the previous post in this caching related series I&#8217;ve received many questions on hardware and software configuration of our servers so in this post I&#8217;ll describe our server&#8217;s configs and the motivation behind those configs.

Hardware Configuration
Since in our setup Squid server uses one-process model (with an asynchronous requests processing) there was no point in ordering multi-core CPUs for our boxes and since we have a lots of pages on the site and the cache is pretty huge all the servers ended up being highly I/O bound. Considering these facts we&#8217;ve decided to use the following hardware specs for the servers:
CPU: One pretty cheap dual-core Intel Xeon 5148 (no need in multiple cores or really high frequencies &#8211; even these CPUs have ~1% avg load)
RAM: 8Gb (basically to reduce I/O pressure by caching hot content in RAM)
Disks:  4 x small SAS 15k drives in JBOD mode (no RAIDS &#8211; we&#8217;ve tried all kinds of RAID configs and it did not help with the I/O performance)
So, once again: nothing is as important in a squid box as I/O throughput. 
Here is a sample CPU load graph from one of the boxes:

Software Configuration
This could be a long story, but in a few words our experience with different squid versions was the following.
First, when I&#8217;ve started working on this caching project I&#8217;ve just installed squid using Debian&#8217;s apt-get install squid command. As the result we&#8217;ve got some ancient squid 2.6 release that for some reason (still unclear to me) was painfully slow in I/O operations and it had some leaking file descriptors problem so after a few hours under production load the box would simply stop processing requests.
When the first approach failed, I&#8217;ve decided to go to the squid web site, download the latest production release and install it from sources (yes, we do it all the time when OS vendor ships too old or buggy releases). Result &#8211; freaking fast and stable squid 3.0 which worked flawlessly for about 5 months. 
Few months ago we&#8217;ve found out about the stale-* extensions available in squid 2.7 and I&#8217;ve started wondering if we should change our perfectly stable 3.0 setup to 2.7. And some time later I&#8217;ve decided to use Vary HTTP header in our caching architecture and then I found out that vary-caching correctly implemented only in 2.7 and since 3.0 is a complete rewrite of the 2.X branch, vary-caching is not yet implemented there (or not in a way we&#8217;d want it to be implemented).
So, the  final result: at this moment in time we&#8217;re using custom-built Squid 2.7STABLE6 and really happy with it, it is stable, fast and feature-rich caching proxy server.
Caching Cluster Configuration
Apparently we have more than one squid server in scribd and this makes it a bit harder to use those servers (comparing to one box when you&#8217;d send all requests to one IP:port pair). We&#8217;ve tried to use round-robin balancing for the squid boxes + ICP-based neighbor checks but it was adding more latency to our responses and we&#8217;ve decided to put haproxy load balancer between nginx and squid farm and set up URL hash based balancing to distribute requests evenly amongst squid backends. 
This scheme worked pretty nice, but we had one serious problem with this setup: if one squid box would go down, haproxy would quickly detect the problem and would remove it from the pool&#8230; And here comes the problem &#8211; removing a server from the pool completely changes hashing keys space and all cached requests become invalid. To solve this problem we&#8217;ve developed a nginx balancer module that performs consistent hashing of URLs and we&#8217;re testing this module now in production. What is really good about this module is that it removes one hop from the chain if http proxies between the site and a user.
So, this was a short description of what hardware we use for our caching cluster and why do we use it. In the next posts of this series we&#8217;ll talk about cache control and objects invalidation.



  
]]></description>
			<content:encoded><![CDATA[<p>After <a href="http://kovyrin.net/2009/07/21/advanced-squid-caching-scribd-logged-in-users-complex-urls/">the previous post in this caching related series</a> I&#8217;ve received many questions on hardware and software configuration of our servers so in this post I&#8217;ll describe our server&#8217;s configs and the motivation behind those configs.</p>
<p><span></span></p>
<h3>Hardware Configuration</h3>
<p>Since in our setup Squid server uses one-process model (with an asynchronous requests processing) there was no point in ordering multi-core CPUs for our boxes and since we have a lots of pages on the site and the cache is pretty huge all the servers ended up being highly I/O bound. Considering these facts we&#8217;ve decided to use the following hardware specs for the servers:</p>
<p><b>CPU:</b> One pretty cheap dual-core Intel Xeon 5148 (no need in multiple cores or really high frequencies &#8211; even these CPUs have ~1% avg load)<br />
<b>RAM:</b> 8Gb (basically to reduce I/O pressure by caching hot content in RAM)<br />
<b>Disks: </b> 4 x small SAS 15k drives in JBOD mode (no RAIDS &#8211; we&#8217;ve tried all kinds of RAID configs and it did not help with the I/O performance)</p>
<p>So, once again: <i>nothing is as important in a squid box as I/O throughput</i>. </p>
<p>Here is a sample CPU load graph from one of the boxes:</p>
<p><a href="http://kovyrin.net/wp-content/uploads/2009/08/squid-cpu-graph.png"><img src="http://kovyrin.net/wp-content/uploads/2009/08/squid-cpu-graph-300x139.png" alt="squid-cpu-graph" title="squid-cpu-graph" width="300" height="139" class="aligncenter size-medium wp-image-305" /></a></p>
<h3>Software Configuration</h3>
<p>This could be a long story, but in a few words our experience with different squid versions was the following.</p>
<p>First, when I&#8217;ve started working on this caching project I&#8217;ve just installed squid using Debian&#8217;s apt-get install squid command. As the result we&#8217;ve got some ancient squid 2.6 release that for some reason (still unclear to me) was painfully slow in I/O operations and it had some leaking file descriptors problem so after a few hours under production load the box would simply stop processing requests.</p>
<p>When the first approach failed, I&#8217;ve decided to go to the <a href="http://www.squid-cache.org/">squid web site</a>, download the latest production release and install it from sources (yes, we do it all the time when OS vendor ships too old or buggy releases). Result &#8211; freaking fast and stable squid 3.0 which worked flawlessly for about 5 months. </p>
<p>Few months ago we&#8217;ve found out about the <a href="http://www.mnot.net/blog/2007/12/12/stale">stale-* extensions</a> available in squid 2.7 and I&#8217;ve started wondering if we should change our perfectly stable 3.0 setup to 2.7. And some time later I&#8217;ve decided to use Vary HTTP header in our caching architecture and then I found out that vary-caching correctly implemented only in 2.7 and since 3.0 is a complete rewrite of the 2.X branch, vary-caching is not yet implemented there (or not in a way we&#8217;d want it to be implemented).</p>
<p>So, the  final result: at this moment in time we&#8217;re using custom-built Squid 2.7STABLE6 and really happy with it, it is stable, fast and feature-rich caching proxy server.</p>
<h3>Caching Cluster Configuration</h3>
<p>Apparently we have more than one squid server in scribd and this makes it a bit harder to use those servers (comparing to one box when you&#8217;d send all requests to one IP:port pair). We&#8217;ve tried to use round-robin balancing for the squid boxes + ICP-based neighbor checks but it was adding more latency to our responses and we&#8217;ve decided to put haproxy load balancer between nginx and squid farm and set up URL hash based balancing to distribute requests evenly amongst squid backends. </p>
<p>This scheme worked pretty nice, but we had one serious problem with this setup: if one squid box would go down, haproxy would quickly detect the problem and would remove it from the pool&#8230; And here comes the problem &#8211; removing a server from the pool completely changes hashing keys space and all cached requests become invalid. To solve this problem we&#8217;ve developed a nginx balancer module that performs consistent hashing of URLs and we&#8217;re testing this module now in production. What is really good about this module is that it removes one hop from the chain if http proxies between the site and a user.</p>
<p>So, this was a short description of what hardware we use for our caching cluster and why do we use it. In the next posts of this series we&#8217;ll talk about cache control and objects invalidation.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/CCp90YJkbcR5Mr-i71FKxJDXc08/0/da"><img src="http://feedads.g.doubleclick.net/~a/CCp90YJkbcR5Mr-i71FKxJDXc08/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/CCp90YJkbcR5Mr-i71FKxJDXc08/1/da"><img src="http://feedads.g.doubleclick.net/~a/CCp90YJkbcR5Mr-i71FKxJDXc08/1/di" border="0" ismap="true"></img></a></p><div>
<a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=s8GVmmmES8s:rOiXzkyoXvI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=s8GVmmmES8s:rOiXzkyoXvI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=s8GVmmmES8s:rOiXzkyoXvI:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Homo-Adminus?a=s8GVmmmES8s:rOiXzkyoXvI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Homo-Adminus?i=s8GVmmmES8s:rOiXzkyoXvI:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2009/08/04/advanced-squid-caching-in-scribd-hardware-software-used/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Social Networks for MySQL Community</title>
		<link>http://blogs.sun.com/dups/entry/social_networks_for_mysql_community?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=social-networks-for-mysql-community</link>
		<comments>http://blogs.sun.com/dups/entry/social_networks_for_mysql_community#comments</comments>
		<pubDate>Fri, 31 Jul 2009 23:04:29 +0000</pubDate>
		<dc:creator>Duleepa 'Dups' Wijayawardhana</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[social]]></category>

		<guid isPermaLink="false">http://blogs.sun.com/dups/entry/social_networks_for_mysql_community</guid>
		<description><![CDATA[One of the things about working with MySQL Community is trying to reach you all. If you are reading this then we have reached you.&#160; Talking about community is frankly about where our community exists, where you chat and feel comfortable. To that end we've created a poll about where you might be intrested in hearing *from* us. Please, do let us know which social network you are interested in here from us! There is no ulterior motive, the poll is anonymous, but it gives us some crucial information on where you want to interact with us, or where we might begin to ask the questions.Check out the poll.]]></description>
			<content:encoded><![CDATA[One of the things about working with MySQL Community is trying to reach you all. If you are reading this then we have reached you.&nbsp; Talking about community is frankly about where our community exists, where you chat and feel comfortable. To that end we've created a poll about where you might be intrested in hearing *from* us. <a href="http://dev.mysql.com/tech-resources/quickpolls/">Please, do let us know which social network you are interested in here from us</a>! <br /><br />There is no ulterior motive, the poll is anonymous, but it gives us some crucial information on where you want to interact with us, or where we might begin to ask the questions.<br /><a href="http://dev.mysql.com/tech-resources/quickpolls/"><br />Check out the poll.</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2009/08/01/social-networks-for-mysql-community/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

