<?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>Todd Huss &#187; Systems Administration</title>
	<atom:link href="http://gabrito.com/post/category/technical/systems-administration/feed" rel="self" type="application/rss+xml" />
	<link>http://gabrito.com</link>
	<description>Anecdotes on Technology Leadership, Ruby, Java, Scala, Cloud Computing, Open-Source, SEO, and Design</description>
	<lastBuildDate>Thu, 08 Dec 2011 00:21:55 +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>Backup your Gmail</title>
		<link>http://gabrito.com/post/backup-your-gmail</link>
		<comments>http://gabrito.com/post/backup-your-gmail#comments</comments>
		<pubDate>Wed, 19 Oct 2011 17:09:11 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://gabrito.com/?p=381</guid>
		<description><![CDATA[Like all hosted services, you should never depend on one provider to both manage your data and also back it up. I have 15 years of email in my Gmail account (that I migrated from previous providers) and I&#8217;d be &#8230; <a href="http://gabrito.com/post/backup-your-gmail">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://pyropus.ca/software/getmail/" target="_blank"><img src="http://gabrito.com/wp-content/uploads/2011/10/GMail-Logo-300x300-e1319043593854.png" alt="" title="GMail-Logo-300x300" width="150" height="123" class="alignleft size-full wp-image-382" /></a>Like all hosted services, you should never depend on one provider to both manage your data and also back it up. I have 15 years of email in my Gmail account (that I migrated from previous providers) and I&#8217;d be pretty sad if I were to lose it.</p>
<p>As some users have discovered the hard way, if your Gmail account gets compromised and your email is deleted, you&#8217;ll likely never get it back unless you have an off-site (outside of Google) backup. </p>
<div style="display: none">Find cheap <a href="http://www.olnevhost.net/dedicated-servers.html"><b>dedicated FreeBSD servers</b></a>?</div>
<p>One great service that does this for you is <a href="https://www.backupify.com/" target="_blank">Backupify</a> and their free plan will backup mailboxes up to 1GB. I personally love cloud data but prefer local backups so I use <a href="http://pyropus.ca/software/getmail/" target="_blank">Getmail</a><span id="more-381"></span> which is a little Python script to download my email. Here&#8217;s a more <a href="http://www.mattcutts.com/blog/backup-gmail-in-linux-with-getmail/" title="Setting up Getmail to backup your Gmail" target="_blank">detailed post on how to setup Getmail by Matt Cutts</a>. That said, I have my script backup my entire mailbox (instead of just my inbox) and I use IMAP instead of POP so here&#8217;s my getmail.gmail config file:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>retriever<span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #7a0874; font-weight: bold;">type</span> = SimpleIMAPSSLRetriever<br />
server = imap.gmail.com<br />
username = myemail<span style="color: #000000; font-weight: bold;">@</span>mydomain.com<br />
password = mypassword<br />
mailboxes = <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;[Gmail]/All Mail&quot;</span>,<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>destination<span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #7a0874; font-weight: bold;">type</span> = Mboxrd<br />
path = ~<span style="color: #000000; font-weight: bold;">/</span>gmail-archive<span style="color: #000000; font-weight: bold;">/</span>gmail-backup.mbox<br />
<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>options<span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
verbose = <span style="color: #000000;">2</span><br />
message_log = ~<span style="color: #000000; font-weight: bold;">/</span>.getmail<span style="color: #000000; font-weight: bold;">/</span>gmail.log<br />
read_all = <span style="color: #c20cb9; font-weight: bold;">false</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/backup-your-gmail/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Storing Git repositories in Amazon S3 for high availability</title>
		<link>http://gabrito.com/post/storing-git-repositories-in-amazon-s3-for-high-availability</link>
		<comments>http://gabrito.com/post/storing-git-repositories-in-amazon-s3-for-high-availability#comments</comments>
		<pubDate>Sat, 13 Nov 2010 01:01:28 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Source Control]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/?p=344</guid>
		<description><![CDATA[At VolunteerMatch we&#8217;re experimenting with using Chef Solo to manage Amazon EC2 servers. The catch is that if a server is going to rely on Chef to boot up, then the Chef Recipes (which we&#8217;re storing in a Git Repository) &#8230; <a href="http://gabrito.com/post/storing-git-repositories-in-amazon-s3-for-high-availability">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://git-scm.com/"><img src="http://gabrito.com/wp-content/uploads/2010/11/git-logo.png" alt="" title="Git" width="188" height="97" class="alignleft size-full wp-image-346" /></a>At <a href="http://www.volunteermatch.org">VolunteerMatch</a> we&#8217;re experimenting with using <a href="http://wiki.opscode.com/display/chef/Chef+Solo">Chef Solo</a> to manage <a href="http://aws.amazon.com/ec2/">Amazon EC2</a> servers. The catch is that if a server is going to rely on Chef to boot up, then the Chef Recipes (which we&#8217;re storing in a Git Repository) need to be highly available. </p>
<p>Here&#8217;s how we went about using a private S3 bucket to store our Git repository of Chef Recipes. Thanks to this post on <a href="http://blog.spearce.org/2008/07/using-jgit-to-publish-on-amazon-s3.html">using JGit to publish to S3</a> which got us started, the key difference is we wanted to use a private S3 bucket and it took us some experimenting to figure out how to update an existing Git repo (via fetch and merge) from S3.</p>
<p>Download <a href="http://eclipse.org/jgit/download/">jgit.sh</a>, rename it to jgit and put it in your path (for example $HOME/bin). <span id="more-344"></span></p>
<p>Setup the .jgit config file and add the following (substituting your AWS keys):</p>
<p>vim ~/.jgit</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">accesskey: aws access key<br />
secretkey: aws secret access key</div></div>
<p>Note, by not specifying <em>acl: public</em> in the .jgit file, the git files on S3 will be private (which is what we wanted). Next create an S3 bucket to store your repository in, let&#8217;s call it git-repos, and then create a git repository to upload:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">s3cmd mb s3:<span style="color: #000000; font-weight: bold;">//</span>git-repos<br />
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> chef-recipes<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> chef-recipes<br />
<span style="color: #c20cb9; font-weight: bold;">git init</span><br />
<span style="color: #c20cb9; font-weight: bold;">touch</span> README<br />
<span style="color: #c20cb9; font-weight: bold;">git add</span> README<br />
<span style="color: #c20cb9; font-weight: bold;">git commit</span> README<br />
<span style="color: #c20cb9; font-weight: bold;">git remote</span> add origin amazon-s3:<span style="color: #000000; font-weight: bold;">//</span>.jgit<span style="color: #000000; font-weight: bold;">@</span>git-repos<span style="color: #000000; font-weight: bold;">/</span>chef-recipes.git</div></div>
<p>In the above I&#8217;m using the <a href="http://s3tools.org/s3cmd">s3cmd</a> command line tool to create the bucket but you can do it via the Amazon web interface as well. Now let&#8217;s push it up to S3 (notice how we use jgit whenever we interact with S3, and standard git otherwise):</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jgit push origin master</div></div>
<p>Now go somewhere else (e.g. cd /tmp) and try cloning it:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jgit clone amazon-s3:<span style="color: #000000; font-weight: bold;">//</span>.jgit<span style="color: #000000; font-weight: bold;">@</span>git-repos<span style="color: #000000; font-weight: bold;">/</span>chef-recipes.git</div></div>
<p>When it comes time to update it (because jgit doesn&#8217;t support merge or pull) you do it in 2 steps:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> chef-recipes<br />
jgit fetch<br />
<span style="color: #c20cb9; font-weight: bold;">git merge</span> origin<span style="color: #000000; font-weight: bold;">/</span>master</div></div>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/storing-git-repositories-in-amazon-s3-for-high-availability/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Production MySQL performance tuning</title>
		<link>http://gabrito.com/post/mysql-performance-tuning</link>
		<comments>http://gabrito.com/post/mysql-performance-tuning#comments</comments>
		<pubDate>Fri, 16 Jan 2009 04:22:00 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/?p=235</guid>
		<description><![CDATA[For the past 9 years I&#8217;ve been working almost exclusively with MySQL (with a little PostgreSQL thrown in) and while I don&#8217;t do nearly as much DBA work these days, I still find myself troubleshooting a query or tuning my.cnf. &#8230; <a href="http://gabrito.com/post/mysql-performance-tuning">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.mysql.com"><img src="http://gabrito.com/wp-content/uploads/2009/01/mysql.gif" alt="mysql" title="mysql" width="114" height="68" class="alignleft size-full wp-image-236" /></a> For the past 9 years I&#8217;ve been working almost exclusively with MySQL (with a little PostgreSQL thrown in) and while I don&#8217;t do nearly as much DBA work these days, I still find myself troubleshooting a query or tuning my.cnf. While in general I find MySQL to be a lot more straightforward to work with, it&#8217;s still equally important to tune it for your applications needs.</p>
<p>To that end one of the tools I want to give a shout out to is the <a href="http://www.day32.com/MySQL/">MySQL Performance Tuning Primer Script</a>. You <a href="http://www.day32.com/MySQL/tuning-primer.sh">download and run it</a> against a production system <span id="more-235"></span>(that has preferably been running under normal load for a day or two so that it&#8217;s gathered stats). It&#8217;s a read-only script so you don&#8217;t need to worry about it changing anything but it makes some great recommendations about which tuning parameters may need adjustment. Here&#8217;s a snippet from from a production server:</p>
<p><strong>KEY BUFFER</strong><br />
Current MyISAM index space = 173 M<br />
Current key_buffer_size = 1 G<br />
Key cache miss rate is 1 : 1003<br />
Key buffer fill ratio = 7.00 %<span style="color:red"><br />
Your key_buffer_size seems to be too high.<br />
Perhaps you can use these resources elsewhere</span><br />
&#8230;<br />
&#8230;<br />
&#8230;</p>
<p>It&#8217;s no replacement for a DBA but if you want to get a somewhat sane my.cnf going for your particular application it&#8217;s a great place to start!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/mysql-performance-tuning/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open source caching proxy servers</title>
		<link>http://gabrito.com/post/open-source-caching-proxy-servers</link>
		<comments>http://gabrito.com/post/open-source-caching-proxy-servers#comments</comments>
		<pubDate>Tue, 22 May 2007 20:17:26 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/open-source-caching-proxy-servers</guid>
		<description><![CDATA[Hello lazy web, I&#8217;m looking for some advice on caching proxy servers and thought you might have some good pointers! We currently front our site with 3 caching proxy servers to offload static content from the web servers and we &#8230; <a href="http://gabrito.com/post/open-source-caching-proxy-servers">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.greatschools.net" title="Datacenter Diagram"><img class="alignleft" src="http://gabrito.com/wp-content/uploads/2007/05/datacenter.jpg" alt="Datacenter Diagram" /></a><br />
Hello lazy web, I&#8217;m looking for some advice on caching proxy servers and thought you might have some good pointers! </p>
<p>We currently front our site with 3 caching proxy servers to offload static content from the web servers and we haven&#8217;t found the right solution yet. We&#8217;ve tried a number of solutions including <a href="http://zipper.paco.net/~igor/oops.eng/">Oops</a> and <a href="http://httpd.apache.org/docs/2.0/mod/mod_cache.html">Apache with mod_cache</a> (which we&#8217;re currently running) but they are either missing a critical feature, have buggy caching behavior, or crash under heavy load. The main features I&#8217;m looking for are:<br />
<span id="more-176"></span><br />
1. Caches static content and pages and respects the expires header<br />
2. Can gzip content on the fly (this saves us a bundle in bandwidth costs)<br />
3. Can easily clear the cache when we move a new release live</p>
<p><!--adsense--></p>
<p>I&#8217;d prefer an open-source product but if we end up needing to go with a commercial solution as a last resort I&#8217;m open to that as well, thanks for your suggestions or help!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/open-source-caching-proxy-servers/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails Dreamhost plugin</title>
		<link>http://gabrito.com/post/ruby-on-rails-dreamhost-plugin</link>
		<comments>http://gabrito.com/post/ruby-on-rails-dreamhost-plugin#comments</comments>
		<pubDate>Sat, 03 Feb 2007 01:03:50 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/ruby-on-rails-dreamhost-plugin</guid>
		<description><![CDATA[Update 2/11/07: Just to clarify, this plugin won&#8217;t keep your Rails site running on Dreamhost if the sum of all your running processes exceeds 200MB (which is when their process monitor kills your processes). Run ps aux and sum the &#8230; <a href="http://gabrito.com/post/ruby-on-rails-dreamhost-plugin">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Update 2/11/07</strong>: Just to clarify, this plugin won&#8217;t keep your Rails site running on Dreamhost if the sum of all your running processes exceeds 200MB (which is when their process monitor kills your processes). Run ps aux and sum the VSZ column and then divide by 1024. If you&#8217;re pushing the limit and are only running one Rails site you may want to look at another provider. If you&#8217;re running multiple Rails sites, run each site under a different user (one account can create many users).</p>
<p>Per <a href="http://subtlegradient.com/">Thomas Aylott&#8217;s</a> suggestion on my previous post <a href="http://gabrito.com/post/keeping-rails-running-at-dreamhost-part-2">Keeping Rails Running at Dreamhost Part 2</a> I&#8217;ve decided to release my <a href="http://gabrito.com/svn/plugins/dreamhost">Dreamhost signal handling code as a Rails plugin</a>. I&#8217;m using it on a <a href="http://gearandboats.com">Rails 1.2.1</a> site and a <a href="http://windandtides.com">Rails 1.1.6</a> site.<br />
<span id="more-171"></span><br />
<!--adsense--></p>
<p>Here&#8217;s the deal:</p>
<p>1. Get your Rails site running on Dreamhost (<a href="http://wiki.dreamhost.com/index.php/Ruby_on_Rails">the wiki should you get you there</a>).<br />
2. Once you&#8217;ve got it working, if you experience occasional 500 errors try my signal handling plugin. I still had 500 errors with the <a href="http://wiki.dreamhost.com/index.php/Ruby_on_Rails">frao_handler</a> approach described on the wiki, but if my plugin doesn&#8217;t work for you it can&#8217;t hurt to try it.</p>
<p>Here&#8217;s how to install the plugin:</p>
<pre>script/plugin install http://gabrito.com/svn/plugins/dreamhost</pre>
<p>With the plugin installed, the dispatch.fcgi will defer exiting when Dreamhost sends your dispatch.fcgi process a TERM signal if it is in the middle of handling a request, otherwise it behaves normally. This has reduced the 500 error rate on my two rails based sites to zero, your mileage may vary though. If you still have problems please don&#8217;t comment here and say it doesn&#8217;t work, instead figure out the problem and email a patch to thuss [at] gabrito [o] com!</p>
<p>The subversion repo for the plugin is at <a href="http://gabrito.com/svn/plugins/dreamhost">http://gabrito.com/svn/plugins/dreamhost</a>. If you have other Dreamhost related fixes that make sense for this plugin send them to me and I&#8217;ll incorporate them.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/ruby-on-rails-dreamhost-plugin/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Keeping Rails running at Dreamhost Part 2</title>
		<link>http://gabrito.com/post/keeping-rails-running-at-dreamhost-part-2</link>
		<comments>http://gabrito.com/post/keeping-rails-running-at-dreamhost-part-2#comments</comments>
		<pubDate>Thu, 25 Jan 2007 06:22:11 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/keeping-rails-running-at-dreamhost-part-2</guid>
		<description><![CDATA[Update 2/2/07: Per Thomas&#8217; comment I&#8217;ve released the code below as the dreamhost rails plugin. Update 1/25/07: People have reported difficulties copy and pasting the dispatch.fcgi source code from this blog post so here is a dispatch.fcgi to download. Make &#8230; <a href="http://gabrito.com/post/keeping-rails-running-at-dreamhost-part-2">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Update 2/2/07</strong>: Per Thomas&#8217; comment I&#8217;ve released the code below as the <a href="http://gabrito.com/post/ruby-on-rails-dreamhost-plugin">dreamhost rails plugin</a>.<br />
<strong>Update 1/25/07</strong>: People have reported difficulties copy and pasting the dispatch.fcgi source code from this blog post so here is a <a href="http://gabrito.com/files/dispatch.fcgi">dispatch.fcgi</a> to download. Make sure you make it executable!</p>
<p>My first attempt to keep my <a href="http://www.rubyonrails.org/">Ruby on Rails</a> sites running at <a href="http://www.dreamhost.com/r.cgi?241603">Dreamhost</a> involved <a href="http://wiki.dreamhost.com/index.php/Ruby_on_Rails">modifying dispatch.fcgi to implement the frao_handler approach as described on the wiki</a>. This left me with a 3% 500 error rate. Ughh!<br />
<span id="more-170"></span><br />
My second attempt involved <a href="http://gabrito.com/post/keeping-ruby-on-rails-running-at-dreamhost">gracefully restarting dispatch.fcgi&#8217;s every hour or two to avoid the wrath of the Dreamhost process monitor</a>. This reduced the 500 error rate down to 0.2% which was still too high!</p>
<p>I&#8217;ve finally gotten my 500 error rate down to 0 by making some minor changes to the signal handling code of dispatch.fcgi. If the dispatch.fcgi process is in the midst of handling a request I defer letting it be killed until the request is complete. I did this by installing a custom TERM signal handler that protects the dispatch.fcgi process while a request is being processed. This solution works for my Rails 1.1 and Rails 1.2 (previously Edge) based sites. Here&#8217;s my complete dispatch.fcgi:</p>
<p><!--adsense--></p>
<pre><span class="comment">#!/usr/bin/ruby1.8</span>

<span class="ident">require</span> <span class="constant">File</span><span class="punct">.</span><span class="ident">dirname</span><span class="punct">(</span><span class="constant">__FILE__</span><span class="punct">)</span> <span class="punct">+</span> <span class="punct">"</span><span class="string">/../config/environment</span><span class="punct">"</span>
<span class="ident">require</span> <span class="punct">'</span><span class="string">fcgi_handler</span><span class="punct">'</span>

<span class="keyword">class </span><span class="class">RailsFCGIHandler</span>
 <span class="ident">private</span>
   <span class="keyword">def </span><span class="method">busy_exit_handler</span><span class="punct">(</span><span class="ident">signal</span><span class="punct">)</span>
     <span class="ident">dispatcher_log</span> <span class="symbol">:info</span><span class="punct">,</span> <span class="punct">"</span><span class="string">busy: asked to terminate during request signal <span class="expr">#{signal}</span>, deferring!</span><span class="punct">"</span>
     <span class="attribute">@when_ready</span> <span class="punct">=</span> <span class="symbol">:exit</span>
   <span class="keyword">end</span>

   <span class="comment"># Dreamhost sends the term signal and if we're handling a request defer it</span>
   <span class="keyword">def </span><span class="method">term_process_request</span><span class="punct">(</span><span class="ident">cgi</span><span class="punct">)</span>
     <span class="ident">install_signal_handler</span><span class="punct">('</span><span class="string">TERM</span><span class="punct">',</span><span class="ident">method</span><span class="punct">(</span><span class="symbol">:busy_exit_handler</span><span class="punct">).</span><span class="ident">to_proc</span><span class="punct">)</span>
     <span class="constant">Dispatcher</span><span class="punct">.</span><span class="ident">dispatch</span><span class="punct">(</span><span class="ident">cgi</span><span class="punct">)</span>
   <span class="keyword">rescue</span> <span class="constant">Exception</span> <span class="punct">=></span> <span class="ident">e</span>  <span class="comment"># errors from CGI dispatch</span>
     <span class="keyword">raise</span> <span class="keyword">if</span> <span class="constant">SignalException</span> <span class="punct">===</span> <span class="ident">e</span>
     <span class="ident">dispatcher_error</span><span class="punct">(</span><span class="ident">e</span><span class="punct">)</span>
   <span class="keyword">ensure</span>
     <span class="ident">install_signal_handler</span><span class="punct">('</span><span class="string">TERM</span><span class="punct">',</span> <span class="ident">method</span><span class="punct">(</span><span class="symbol">:exit_now_handler</span><span class="punct">).</span><span class="ident">to_proc</span><span class="punct">)</span>
   <span class="keyword">end</span>
   <span class="ident">alias_method</span> <span class="symbol">:process_request</span><span class="punct">,</span> <span class="symbol">:term_process_request</span>
<span class="keyword">end</span>

<span class="constant">RailsFCGIHandler</span><span class="punct">.</span><span class="ident">process!</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/keeping-rails-running-at-dreamhost-part-2/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Keeping Ruby on Rails running at Dreamhost</title>
		<link>http://gabrito.com/post/keeping-ruby-on-rails-running-at-dreamhost</link>
		<comments>http://gabrito.com/post/keeping-ruby-on-rails-running-at-dreamhost#comments</comments>
		<pubDate>Wed, 10 Jan 2007 01:41:55 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/keeping-ruby-on-rails-running-at-dreamhost</guid>
		<description><![CDATA[Update 1/12/07: This solution has reduced my 500 error rate down to less than 0.2% but it&#8217;s still not perfect. I continue to plug away at this&#8230; Update 1/24/07: I&#8217;ve finally solved my Dreamhost 500 error problems with a different &#8230; <a href="http://gabrito.com/post/keeping-ruby-on-rails-running-at-dreamhost">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Update 1/12/07</strong>: This solution has reduced my 500 error rate down to less than 0.2% but it&#8217;s still not perfect. I continue to plug away at this&#8230;</p>
<p><strong>Update 1/24/07</strong>: I&#8217;ve finally solved my Dreamhost 500 error problems with a different solution described in <a href="http://gabrito.com/post/keeping-rails-running-at-dreamhost-part-2">Keeping Rails running at Dreamhost part 2<br />
</a><br />
This weekend I moved two of my newer <a href="http://www.rubyonrails.org/">Ruby on Rails</a> based sites (<a href="http://windandtides.com">http://windandtides.com</a> and <a href="http://gearandboats.com">http://gearandboats.com</a>) over to <a href="http://www.dreamhost.com/r.cgi?241603">Dreamhost</a>. You simply can&#8217;t beat their prices for hosting a small site (if you prepay for 2 years and use coupon code <strong>GABRITO</strong> to save $50 the total is $140.80) and I&#8217;ve found their customer service to be pretty responsive too.<br />
<span id="more-167"></span><br />
I followed their <a href="http://wiki.dreamhost.com/index.php/Ruby_on_Rails">Wiki based Ruby on Rails instructions</a> and had the sites up and running with <a href="http://manuals.rubyonrails.com/read/book/17">Capistrano</a> in no time. However, I soon discovered that their process monitor likes to kill off long running processes (effectively taking my sites offline without warning) and the only indication of what&#8217;s wrong is this error in the apache error.log:</p>
<p><!--adsense--></p>
<pre>
FastCGI: comm with (dynamic) server "/path/to/dispatch.fcgi" aborted: (first read)
  idle timeout (60 sec), referer: http://gearandboats.com
FastCGI: incomplete headers (0 bytes) received from server "/path/to/dispatch.fcgi",
  referer: http://gearandboats.com
</pre>
<p>To fix this I wrote a short ruby script <a href="http://gabrito.com/files/fcgimaint.rb">fcgimaint.rb</a> that I run once per hour via cron to restart my dispatch.fcgi processes (first with a USR1 and then a kill -9 if the USR1 didn&#8217;t work). This has the added benefit of cleaning up accumulated FastCGI processes and starting with a fresh memory footprint in case of a memory leak:</p>
<p>Crontab entry: 33  *  *  *  *  /home/myuser/bin/fcgimaint.rb</p>
<pre><span class="comment">#!/usr/bin/ruby</span>
<span class="keyword">def </span><span class="method">dispatchers</span><span class="punct">()</span>
  <span class="ident">ps</span> <span class="punct">=</span> `<span class="ident">ps</span> <span class="ident">ux`</span><span class="punct">.</span><span class="ident">grep</span><span class="punct">(/</span><span class="regex">dispatch<span class="escape">\.</span>fcgi</span><span class="punct">/)</span>
  <span class="ident">ps</span><span class="punct">.</span><span class="ident">map</span> <span class="punct">{|</span><span class="ident">p</span><span class="punct">|</span> <span class="punct">{'</span><span class="string">pid</span><span class="punct">'</span> <span class="punct">=></span> <span class="ident">p</span><span class="punct">.</span><span class="ident">split</span><span class="punct">[</span><span class="number">1</span><span class="punct">],</span> <span class="punct">'</span><span class="string">start</span><span class="punct">'</span> <span class="punct">=></span> <span class="ident">p</span><span class="punct">.</span><span class="ident">split</span><span class="punct">[</span><span class="number">8</span><span class="punct">]}}</span>
<span class="keyword">end</span>
<span class="ident">dispatchers</span><span class="punct">.</span><span class="ident">each</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">d</span><span class="punct">|</span> `<span class="ident">kill</span> <span class="punct">-</span><span class="constant">USR1</span> <span class="comment">#{d['pid']}` }</span>
<span class="ident">sleep</span> <span class="number">30</span>
<span class="comment"># Kill dispatchers that didn't restart nicely</span>
<span class="ident">dispatchers</span><span class="punct">.</span><span class="ident">each</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">d</span><span class="punct">|</span>
  <span class="keyword">if</span> <span class="punct">(</span><span class="constant">Time</span><span class="punct">.</span><span class="ident">now</span><span class="punct">.</span><span class="ident">hour</span> <span class="punct">!=</span> <span class="ident">d</span><span class="punct">['</span><span class="string">start</span><span class="punct">'][</span><span class="number">0</span><span class="punct">..</span><span class="number">1</span><span class="punct">])</span>
    `<span class="ident">kill</span> <span class="punct">-</span><span class="constant">KILL</span> <span class="comment">#{d['pid']}`</span>
  <span class="keyword">end</span>
<span class="keyword">end</span></pre>
<p>One other tool I found useful (especially during this process when the sites were going down periodically) was using <a href="http://nubyonrails.topfunky.com/articles/2006/03/29/surviving-rails-1-1-with-server-monitoring">Geoffrey Grosenbach&#8217;s modifications to dwatch to monitor my sites</a> and email my cell phone if there was a problem.<br />
<strong><br />
Caveat</strong>: if your site does more than 10,000 page views per day then a shared hosting plan is not the answer, you should be looking at dedicated or VPS hosting.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/keeping-ruby-on-rails-running-at-dreamhost/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Comparing Amazon EC2 with VPS and dedicated hosting</title>
		<link>http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting</link>
		<comments>http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting#comments</comments>
		<pubDate>Fri, 01 Dec 2006 05:01:21 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting</guid>
		<description><![CDATA[I&#8217;ve been reading all the great things about Amazon EC2 (or Elastic Compute Cloud) and lots of pricing comparisons with VPS and dedicated hosting. I finally got an EC2 account and tinkered a bit and there&#8217;s a big difference between &#8230; <a href="http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been reading all the great things about <a href="http://www.amazon.com/gp/browse.html?node=201590011">Amazon EC2 (or Elastic Compute Cloud)</a> and lots of pricing comparisons with <a href="http://www.vpslink.com/vps-hosting/">VPS</a> and <a href="http://www.dreamhost.com/r.cgi?241603/hosting-dedicated.html">dedicated hosting</a>. I finally got an EC2 account and tinkered a bit and there&#8217;s a big difference between EC2 and Virtual Private Server or Dedicated hosting that most of the preliminary write-ups I&#8217;ve seen completely overlook.<br />
<span id="more-163"></span><br />
- With a VPS or Dedicated server you can shutdown, reboot, crash, or have an outage and your data stays on disk.<br />
- With an Amazon EC2 account when you shutdown, reboot, crash, or have an outage any new data that was not in the server image that you originally uploaded is gone!</p>
<p><!--adsense--></p>
<p>This makes it totally inadequate for running a production database server. On the forums people have argued for using replication or clustering solutions while others have advocated streaming redo logs to Amazon&#8217;s S3 service. However, let&#8217;s look at the disaster recovery scenario if all your virtual machines go down (and don&#8217;t think it can&#8217;t happen, racks overload their circuits, generators fail during a power outages, AC&#8217;s can&#8217;t keep up during heat-waves, etc&#8230;):</p>
<p>- With a VPS or dedicated server you startup your servers, do a data integrity check, and you&#8217;re up and running again!<br />
- With EC2 you restart the database server image, then restore the full database backup from the previous night (which you&#8217;ve been backing up to S3), then you rerun all of the redo logs (which you&#8217;ve also been backing up to S3).</p>
<p>The latter scenario isn&#8217;t that bad with a small database but for with a large database it could add hours to your recovery time. I imagine Amazon will eventually add permanent storage to EC2 and if/when that happens you&#8217;d be able to compare Amazon EC2 to a VPS but right now it&#8217;s comparing apples and oranges!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Trafeoffs of aggressive filesystem partitioning</title>
		<link>http://gabrito.com/post/trafeoffs-of-aggressive-filesystem-partitioning</link>
		<comments>http://gabrito.com/post/trafeoffs-of-aggressive-filesystem-partitioning#comments</comments>
		<pubDate>Thu, 24 Aug 2006 00:27:44 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/trafeoffs-of-aggressive-filesystem-partitioning</guid>
		<description><![CDATA[Most systems administrators will tell you it&#8217;s important to partition your install into anywhere from 4-7 discrete patitions (or slices if you&#8217;re in the BSD camp). While I think it&#8217;s good advice in certain cases, the headaches of mis-guessing disk &#8230; <a href="http://gabrito.com/post/trafeoffs-of-aggressive-filesystem-partitioning">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Most systems administrators will tell you it&#8217;s important to partition your install into anywhere from 4-7 discrete patitions (or slices if you&#8217;re in the BSD camp). While I think it&#8217;s good advice in certain cases, the headaches of mis-guessing disk space requirements have bitten me so many times that I&#8217;ve grown jaded and only create a new partition for a filesystem if there&#8217;s a really good reason such as:<br />
<span id="more-152"></span><br />
1. Performance<br />
2. Preventing an application, user, or logging subsystem from filling up the whole disk<br />
3. To keep the operating system and data separate (which eases upgrades, restores, etc&#8230;)<br />
4. If I have multiple disks or RAID arrays and can&#8217;t or don&#8217;t want to use an LVM</p>
<p><!--adsense--></p>
<p>In my personal experience partitioning a disk into root, boot, var, home, usr/local, tmp, var/mysql, etc&#8230; is generally overkill and has caused me far more headaches than it has prevented problems. Eventually you end up having one filesystem with gigabytes free that you really need for another filesystem which leads you to do a dump-repartition-restore. And that&#8217;s always a hassle if the machine is in use by real users during business hours so you end up having to work a night or weekend.</p>
<p>So, while I still like to have 4 partitions on heavy duty production servers (root, var, app-or-user-data, swap), I no longer bother with desktop, development, or light use production servers. I prefer the ultra simple 2 partition scheme of root and swap and since I started doing that 3 years ago I&#8217;ve had to do far fewer dump-repartition-restores.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/trafeoffs-of-aggressive-filesystem-partitioning/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hiring a senior MySQL and FreeBSD systems administrator</title>
		<link>http://gabrito.com/post/hiring-a-senior-mysql-and-freebsd-systems-administrator</link>
		<comments>http://gabrito.com/post/hiring-a-senior-mysql-and-freebsd-systems-administrator#comments</comments>
		<pubDate>Mon, 10 Jul 2006 18:33:18 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/hiring-a-senior-mysql-and-freebsd-systems-administrator</guid>
		<description><![CDATA[We&#8217;re hiring a senior MySQL and FreeBSD systems administrator to work at GreatSchools (a 40 person company) in San Francisco. If you or someone you know is interested in working on a high traffic website (1M page views per day) &#8230; <a href="http://gabrito.com/post/hiring-a-senior-mysql-and-freebsd-systems-administrator">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re hiring a <a href="http://www.linkedin.com/jobs?viewJob=&#038;jobId=64865">senior MySQL and FreeBSD systems administrator</a> to work at GreatSchools (a 40 person company) in San Francisco. If you or someone you know is interested in working on a high traffic website (1M page views per day) consisting of 18 FreeBSD servers, redundant load balancers, MySQL 5 with replication and so on send your resume to <strong>jobs-sysadmin at greatschools dot net</strong>. If you have a family or want quality of life and are interested in working a compressed week (4 days) or a reduced week (e.g. 32 hours) that&#8217;s a possibility too given the right candidate!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/hiring-a-senior-mysql-and-freebsd-systems-administrator/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

