<?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>Always Get Better &#187; General Programming</title>
	<atom:link href="http://www.alwaysgetbetter.com/blog/category/general-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alwaysgetbetter.com/blog</link>
	<description>Never stop looking for ways to improve</description>
	<lastBuildDate>Mon, 30 Jan 2012 12:00:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>2011 In Review</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/12/31/2011-review/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/12/31/2011-review/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 18:35:13 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Employment]]></category>
		<category><![CDATA[General Programming]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=471</guid>
		<description><![CDATA[photo credit: mikecogh This year started off with a foray into Rails, an experience I won&#8217;t be rushing to complete. Most of my time was spent building a small application during the Christmas break in 2010, but in 2011 I moved that site into production and wrote a little bit about separating production and development [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<div class=alignright><a href="http://www.flickr.com/photos/89165847@N00/6175196194/" title="Hot Desk" target="_blank"><img src="http://farm7.static.flickr.com/6179/6175196194_9689e42f7e_m.jpg" alt="Hot Desk" border="0" /></a><br /><small><a href="http://creativecommons.org/licenses/by-sa/2.0/" title="Attribution-ShareAlike License" target="_blank"><img src="http://www.alwaysgetbetter.com/blog/wp-content/plugins/photo-dropper/images/cc.png" alt="Creative Commons License" border="0" width="16" height="16" align="absmiddle" /></a> <a href="http://www.photodropper.com/photos/" target="_blank">photo</a> credit: <a href="http://www.flickr.com/photos/89165847@N00/6175196194/" title="mikecogh" target="_blank">mikecogh</a></small></div>
<p>This year started off with a foray into Rails, an experience I won&#8217;t be rushing to complete. Most of my time was spent building a small application during the Christmas break in 2010, but in 2011 I moved that site into production and <a href="http://www.alwaysgetbetter.com/blog/2011/03/03/displaying-productiononly-markup-rails/">wrote a little bit about separating production and development values</a> (a feat I repeated for the <a href="http://www.alwaysgetbetter.com/blog/2011/05/09/accessing-configuration-parameters-play-frameworks-template-engine/">Play! framework</a>, which I actually like, later in the year). I think the only thing I really like from Rails, and this is a bit of a stretch, is the <a href="http://www.alwaysgetbetter.com/blog/2011/04/20/database-migrations/">database migrations</a>.</p>
<p>Having moved entirely over to a LAMP platform professionally, and getting good at the <a href="http://www.alwaysgetbetter.com/blog/2011/04/26/protect-ssh-server-rsa-keys/">security nuances</a> plus everything else, I reminisced a little about some of the creature comforts I missed in C#, like <a href="http://www.alwaysgetbetter.com/blog/2011/03/04/defaulting-null-variables/">operators for default null variables</a>. But <a href="http://www.alwaysgetbetter.com/blog/2011/04/15/backup-time/">when I discovered Time Machine</a> on my Mac, there was no going back &#8211; until the company switched directions and I got thrown back into .NET development.</p>
<p>That&#8217;s right &#8211; back to .NET, and deep into the Windows Azure cloud. I dealt with things like figuring out <a href="http://www.alwaysgetbetter.com/blog/2011/04/24/azure-table-storage-azure-sql/">which is better &#8211; table storage or SQL Azure</a>, and figuring out the nuances of their multiple SLAs, and <a href="http://www.alwaysgetbetter.com/blog/2011/04/25/ensure-sla-multiple-web-role-instances-windows-azure/">how to ensure we actually have Azure Compute instances on-line when it hits the fan</a>. At this point <a href="http://www.alwaysgetbetter.com/blog/2011/08/02/windows-azure-thoughts-months/">I have a pretty good handle on Azure&#8217;s strengths and weaknesses</a> and my overall impression of the platform is very positive. If I continue building sites on the Microsoft stack, I would definitely continue to use Azure &#8211; it <em>seems</em> more expensive than other options at first glance, but it has some serious computing power behind it and takes the majority of administration headaches off of my plate. It really has enabled me to, for the most part, just focus on development whereas I was spending an increasing amount of my work day on system administration issues when supporting the LAMP platform.</p>
<p>Scalability and high availability have been on my mind a lot, and I&#8217;ve been looking into some more &#8216;off-beat&#8217; database solutions like <a href="http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/">Drizzle</a> for my transactional needs, as well as <a href="http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/">speeding up existing deployments</a> by <a href="http://www.alwaysgetbetter.com/blog/2011/04/09/memcached-session-handler/">moving as much as possible into RAM</a>. There&#8217;s always a battle between <a href="http://www.alwaysgetbetter.com/blog/2011/04/11/play-framework-saves-world/">changing the way we work to take advantage of the new paradigm</a> or changing our <a href="http://www.alwaysgetbetter.com/blog/2011/04/12/performance-tuning-apache/">existing configuration</a> to get some more life out of it.</p>
<p>The whole cloud computing buzz <a href="http://www.alwaysgetbetter.com/blog/2011/04/05/cloud-computing-magical/">feels tired</a> but has enabled a whole new class of online business. If you have a lot of commodity hardware you can achieve, <a href="http://www.alwaysgetbetter.com/blog/2011/04/21/accelerate-site-content-delivery-network/">very cheaply</a>, <a href="http://www.alwaysgetbetter.com/blog/2011/04/16/small-site-big-footprint/">feats that were only possible with an expensive dedicated network</a> just a few years ago. Sure, it adds a lot of new choke points <a href="http://www.alwaysgetbetter.com/blog/2011/04/19/tracking-website-speed-problems/">you will need good people to help sort through</a>, which is giving rise to a whole new sub-category of programmer specialization to make hiring in 2012 even more challenging.</p>
<p>There is a downside to all the cloud computing, though, as we learned during the high profile <a href="http://www.alwaysgetbetter.com/blog/2011/04/23/surviving-cloud-failures/">Amazon failures &#8211; backups are important</a>. This includes geographically-redundant systems that most organizations don&#8217;t have the experience to deal effectively with just yet. Even so, the biggest lesson I learned was <strong>never let your server run into swap space</strong> or your performance will nose-dive. The growth of this site even prompted me to <a href="http://www.alwaysgetbetter.com/blog/2011/12/20/fastcgi-nginx-performance-vm/">move more of the site into memory</a> which prevented me from needing to spend a lot of money upgrading my infrastructure.</p>
<p>Social media continues to grow, with companies <a href="http://www.alwaysgetbetter.com/blog/2011/04/08/command-control-social-media/">realizing they can&#8217;t control its effect on their business in traditional ways</a> and less-than-useless cons ruining it for everyone by <a href="http://www.alwaysgetbetter.com/blog/2011/04/07/hire-social-media-expert/">selling CEOs on cheap gimmicks</a>.</p>
<p>Since my third child was born in February, I&#8217;ve definitely taken some time to sotp and reflect on what I want to work on, <a href="http://www.alwaysgetbetter.com/blog/2011/04/06/overwork-creative-work-ethic/">why I want to keep working</a>, and what the next steps are career-wise and life-wise. I want to provide the best that I can for my family and 2012 is going to see a radical course change as I start to shift gears and begin building something that will really last, even outlast me. <a href="http://www.alwaysgetbetter.com/blog/2011/04/14/blog-living/">When will my website start paying my bills?</a> I don&#8217;t expect it will.</p>
<p>I learned a lot by running dozens (over a hundred?) <a href="http://www.alwaysgetbetter.com/blog/2011/04/13/interview-process/">job interviews</a> in the past two years. Ignoring the old adage that you shouldn&#8217;t judge a book by it&#8217;s cover, I learned that you <em>can</em> tell with pretty good accuracy whether or not someone will be a good match for your company within the first five minutes of an interview. I&#8217;m less interested in hiring people with domain knowledge than I am in surrounding myself with the most intelligent developers I can find &#8211; one is a skill that can be taught, the other is an aptitude candidates need to bring to the table. Really, when it comes down to it, what I really want is for people I hire to <a href="http://www.alwaysgetbetter.com/blog/2011/04/27/letter-word/">stand up for themselves (since they are adults)</a> and <a href="http://www.alwaysgetbetter.com/blog/2011/04/17/win-work/">make me look good</a> by being awesome at what they do.</p>
<p>I also learned a lot by being responsible for some very large projects; things like <a href="http://www.alwaysgetbetter.com/blog/2011/04/22/rely-continuous-integration/">the importance of continuous integration</a>.</p>
<p>What&#8217;s next in 2012? Look for <a href="http://www.alwaysgetbetter.com/blog/2011/04/28/pintsized-mobile-devices/">mobile device use to continue growth</a> &#8211; every developer who plans to stay employed needs to know something about mobile development, because it&#8217;s going to be ubiquitous with regular desktop programming very soon. Now that version 0.6 has been released with Windows support <a href="http://www.alwaysgetbetter.com/blog/2011/11/07/nodejs-06-released/">is Node.js ready for prime-time</a>? I had the opportunity to play with it a lot over the past few month &#8211; look for a book early in the new year co-authored by yours truly.</p>
<div style="width:468px;margin:0 auto">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-0410364841759590";
/* Homepage, 468x60 ads, After posts, created 12/19/08 */
google_ad_slot = "4210204644";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/12/31/2011-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using FastCGI with Nginx for Performance on a VM</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/12/20/fastcgi-nginx-performance-vm/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/12/20/fastcgi-nginx-performance-vm/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 19:08:08 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[General Programming]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=461</guid>
		<description><![CDATA[This weekend I decided to play around with the configuration on my Rackspace Cloud Server. Since our various websites have been doing well lately, the relatively low-powered machine I am running on is starting to fill up its available RAM. So far so good but as everyone quickly learns &#8211; running out of memory and [...]
Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2012/01/30/setting-wordpress-nginx-fastcgi/' rel='bookmark' title='Setting up WordPress with nginx and FastCGI'>Setting up WordPress with nginx and FastCGI</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/12/performance-tuning-apache/' rel='bookmark' title='Performance Tuning Apache'>Performance Tuning Apache</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This weekend I decided to play around with the configuration on my Rackspace Cloud Server. Since our various websites have been doing well lately, the relatively low-powered machine I am running on is starting to fill up its available RAM. So far so good but as everyone quickly learns &#8211; running out of memory and <a href="http://www.alwaysgetbetter.com/blog/2011/04/12/performance-tuning-apache/">hitting the swap space is a performance killer</a>. Since I want my sites to continue to do well, I decided to take action before they hit the RAM limit and start swapping to disk.</p>
<p><a href="http://www.alwaysgetbetter.com/blog/wp-content/uploads/2011/12/agb_old.png"><img class="alignleft size-full wp-image-462" title="Old Site Architecture" src="http://www.alwaysgetbetter.com/blog/wp-content/uploads/2011/12/agb_old.png" alt="" width="347" height="347" /></a> This is the old architecture I had deployed. Apache &#8211; the Internet&#8217;s workhorse &#8211; to perform all of the PHP processing, with Nginx as a reverse proxy, passing dynamic (PHP) requests to Apache but serving static files directly to <a href="http://www.alwaysgetbetter.com/blog/2010/09/25/give-apache-break-nginx/">give Apache a break</a> and cut down its footprint.</p>
<p>I optimized MySQL with a large buffer, so it serves the vast majority of queries directly from memory.</p>
<p>The two places that hit the filesystem are Nginx and PHP &#8211; Nginx for static files (as mentioned, to take the load of Apache which would spin up a new instance for each file it serves) and PHP for session data (this is PHP&#8217;s default setting).</p>
<p>&nbsp;</p>
<p><a href="http://www.alwaysgetbetter.com/blog/wp-content/uploads/2011/12/agb_new.png"><img class="alignright size-full wp-image-463" title="agb_new" src="http://www.alwaysgetbetter.com/blog/wp-content/uploads/2011/12/agb_new.png" alt="" width="347" height="347" /></a>This is the new setup, and is very similar to the old with two key differences: Apache is gone, and Memcached is now in the mix.</p>
<p>As site traffic increased I noticed that Apache was using up bigger and bigger chunks of the system RAM compared to all of the other processes. I could pare this down by putting further restrictions on the number of child processes, decrease the number of connections before recycling, and limiting the maximum memory for each process, but that seemed like a lot of work when I already had one foot into a more scalable solution.</p>
<p>Taking advantage of the new(ish) since PHP 5.3.3 FastCGI Process Manager (FPM), I updated Nginx to send PHP traffic directly to PHP without using Apache as a middleman. The default settings were too generous for my fairly weak server, and the memory usage shot up. But by tweaking it down to 3 processes recycling after 500 requests, I&#8217;m now using half the physical memory as I was with Apache.</p>
<p>Previously I wrote about using <a href="http://www.alwaysgetbetter.com/blog/2011/04/09/memcached-session-handler/">Memcached as a PHP Session Handler</a> and that&#8217;s exactly what I did here. Now the Filesystem is only hit for static files and the first run of PHP scripts &#8211; everything else is served from memory.</p>
<p>It may seem a little counter-intuitive that I cut memory consumption by moving more services into memory, but the trade-off improvements realized by hitting the disk less means that responses are sent out 30% faster, meaning I can fit more traffic onto the same machine and expect the same responsiveness on the web site.</p>
<p>One thing I could do to improve this even more would be to put Varnish in front of Nginx and serve all static content &#8211; including rendered PHP &#8211; from memory, which would give some seriously (<100ms) fast performance on read-only WordPress pages when users are not logged in. I may do that if traffic continues to rise, but for the moment the combination of Nginx's static file speed with <a href="http://www.alwaysgetbetter.com/blog/2011/04/21/accelerate-site-content-delivery-network/">offloading most of my site&#8217;s static files to a content delivery network (CDN)</a> is giving me the performance I want to see.</p>
<p>Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2012/01/30/setting-wordpress-nginx-fastcgi/' rel='bookmark' title='Setting up WordPress with nginx and FastCGI'>Setting up WordPress with nginx and FastCGI</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/12/performance-tuning-apache/' rel='bookmark' title='Performance Tuning Apache'>Performance Tuning Apache</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/12/20/fastcgi-nginx-performance-vm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Pulled From Mac OS X Lion</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/08/05/mysql-pulled-mac-os-lion/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/08/05/mysql-pulled-mac-os-lion/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 13:41:47 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=439</guid>
		<description><![CDATA[Apple-based LAMP developers be warned: the new version of OS X does not include MySQL, which was formerly part of the developer tools shipped with the operating system. In its place look for deliciously Oracle-free PostgreSQL. Of course, developers can and will continue to download MySQL and install it themselves, but the out-of-box experience moving [...]
Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/18/memcache-mysql/' rel='bookmark' title='Using Memcache with MySQL'>Using Memcache with MySQL</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/' rel='bookmark' title='Drizzle &#8211; MySQL for the Cloud'>Drizzle &#8211; MySQL for the Cloud</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/' rel='bookmark' title='Memcache as MySQL&#8217;s Hero'>Memcache as MySQL&#8217;s Hero</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Apple-based LAMP developers be warned: the new version of OS X does not include MySQL, which was formerly part of the developer tools shipped with the operating system. In its place look for deliciously Oracle-free PostgreSQL. Of course, developers can and will continue to download MySQL and install it themselves, but the out-of-box experience moving forward will be with PostgreSQL.</p>
<p>Although it is still an extremely popular database, Oracle&#8217;s presence in the MySQL world has put a chill over business users considering using the product as the backbone of their data solutions. <a href="http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/">Other databases with similar purposes exists</a> but none have the deep community boasted by PostgreSQL.</p>
<p>Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/18/memcache-mysql/' rel='bookmark' title='Using Memcache with MySQL'>Using Memcache with MySQL</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/' rel='bookmark' title='Drizzle &#8211; MySQL for the Cloud'>Drizzle &#8211; MySQL for the Cloud</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/' rel='bookmark' title='Memcache as MySQL&#8217;s Hero'>Memcache as MySQL&#8217;s Hero</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/08/05/mysql-pulled-mac-os-lion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>It&#8217;s not a four letter word</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/04/27/letter-word/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/04/27/letter-word/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 02:26:16 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[General Programming]]></category>
		<category><![CDATA[work/life balance]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=421</guid>
		<description><![CDATA[Sometimes it seems we have an un-natural fear of the word &#8220;no&#8221;. This might be rooted in childhood memory: when I tell my son &#8220;no&#8221;, I am preventing him from doing something that he wants to do. As a responsible adult, I know the limits I place upon him are for his own protection. As [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Sometimes it seems we have an un-natural fear of the word &#8220;no&#8221;. This might be rooted in childhood memory: when I tell my son &#8220;no&#8221;, I am preventing him from doing something that he wants to do. As a responsible adult, I know the limits I place upon him are for his own protection. As a toddler, he sees &#8220;no&#8221; as a limiter, something that ends a course of inquiry.</p>
<p>I think we have a hard time letting go of our memories. So when a friend, a boss, a client asks us for an unreasonable favour, we are inclined to bend over backwards to deliver. Maybe we&#8217;re afraid that if we say no, our value will somehow be dimished.</p>
<p>I see &#8220;no&#8221; as an invitation. Now we know where the limit is, so we can work to get to a comfortable &#8220;yes&#8221;.</p>
<p>I can&#8217;t help feeling that I once read an article with a similar message to this; if anyone knows what that is, do send me a link!</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/04/27/letter-word/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Database Migrations</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/04/20/database-migrations/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/04/20/database-migrations/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 01:39:32 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Employment]]></category>
		<category><![CDATA[planning]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=404</guid>
		<description><![CDATA[Maintaining database schemas across development environments (especially in teams) and in production can be a real nightmare. Fortunately there are a number of solutions which make database management easier. Migrations This can be done manually or automatically. As database changes are made by developers, scripts are generated which can be run against a master database [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Maintaining database schemas across development environments (especially in teams) and in production can be a real nightmare. Fortunately there are a number of solutions which make database management easier.</p>
<p><strong>Migrations</strong><br />
This can be done manually or automatically. As database changes are made by developers, scripts are generated which can be run against a master database to bring it in line with the developer&#8217;s version. The most basic way to accomplish this is by writing a script manually, but frameworks like Django and Rails have built-in migration tools which manage this process. Rails in particular allows developers to move back and forth between snapshots of database schemas.</p>
<p><strong>Evolutions</strong><br />
Evolutionary systems detect database schema changes against program code definitions. As of April 2011, <a href="http://www.alwaysgetbetter.com/blog/2011/04/11/play-framework-saves-world/">Play Framework supports Evolutions</a>.</p>
<p><strong>Schema Versions</strong><br />
Microsoft SQL Server supports schema versions; wherein the underlying data remains the same, but multiple versions of the database schema rest on top and can be accessed simultaneously. This keeps older versions of the application or supporting clients working with the existing data set.</p>
<p><strong>Keep Tracking&#8230;</strong><br />
Managing database changes can be a challenge for organizations of any size. The correct tool depends on a wide range of factors including your project size, number of team members, release schedule.</p>
<p>What kind of tools and processes do you use to manage database changes?</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/04/20/database-migrations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Memcache with MySQL</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/04/18/memcache-mysql/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/04/18/memcache-mysql/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 00:12:35 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=395</guid>
		<description><![CDATA[MySQL+Memcache have been bedfellows for awhile and at this point are the de facto standard for highly-available, scalable websites. Even with other SQL and NoSQL solutions starting to become popular, this pair holds on as the winner for LAMP programmers. Is the complexity of working with this technology pair worth the investment? Read vs Write [...]
Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/' rel='bookmark' title='Memcache as MySQL&#8217;s Hero'>Memcache as MySQL&#8217;s Hero</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/' rel='bookmark' title='Drizzle &#8211; MySQL for the Cloud'>Drizzle &#8211; MySQL for the Cloud</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/08/05/mysql-pulled-mac-os-lion/' rel='bookmark' title='MySQL Pulled From Mac OS X Lion'>MySQL Pulled From Mac OS X Lion</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>MySQL+Memcache have been bedfellows for awhile and at this point are the de facto standard for highly-available, scalable websites. Even with <a href="http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/">other SQL</a> and NoSQL solutions starting to become popular, this pair holds on as the winner for LAMP programmers. Is the complexity of working with this technology pair worth the investment?</p>
<p><strong>Read vs Write</strong><br />
Traditional relational databases place the burden of computation on read operations. In mainframe environments with powerful servers and relatively few users, this made sense. Database normalization prevents redundancy, and data can be joined together when needed to produce the desired results.</p>
<p>In a web application with 1,000,000 users, the normalized transactional model does not perform. Generally speaking it is way faster to make two queries to a small subset of data rather than attempt expensive joins in a client-facing web site.</p>
<p>Enter memcache: by storing the result of our SQL queries in memory, we improve the speed of subsequent requests by pulling the data from memory as well as avoiding a hit to the database entirely, freeing it to process urgent or real-time requests.</p>
<p><strong>Anatomy of an SQL Query</strong><br />
When we run an SQL query, we are actually asking the server to perform a lot of work:</p>
<ol>
<li>Break down the query into object references: The DBMS needs to understand which tables, columns, and filters you are using by tokenizing your SQL (by breaking out names from the keywords like SELECT, FROM, WHERE).</li>
<li>Identify which indexes (if any) are most relevant to the data: This is harder with more complex queries which must be broken down or which depend on outer tables for their values.</li>
<li>Read the source tables from the hard drive: Most DBMS implementations include some kind of memory caching which partially avoids this expensive read step, but some disk IO is a normal part of operation
<li>Join Columns: If we specify a join, especially a LEFT or RIGHT join, the DBMS has to create a pseudo table from the joined sources in memory before it can do any additional processing.</li>
<li>Sub-selects: Any sub-select statements need to be processed. Depending on how the statement was written, this needs to be done for every row returned in the result set.</li>
<li>Filter and sort: Anything in the &#8216;WHERE&#8217; clause needs to be filtered out of the result set. This is where we are going to start seeing performance improvements by narrowing our result set.</li>
<li>Aggregation: Once the database has its final result set it can do all of the aggregation we ask of it, both calculations and grouping</li>
</ol>
<p>As we can imagine, this can be a time-consuming process. If it is repeated thousands of times in a short period, we will see significant performance loss.</p>
<p><strong>Anatomy of a Cache Request</strong><br />
By contrast, when we perform a request for data from a cache like memcache, we do this:</p>
<ol>
<li>Check the index for the presence of the supplied key</li>
<li>If a result exists, return it</li>
</ol>
<p>In the case of memcache, this happens entirely in memory with no hit to the database whatsoever, resulting in a blindingly fast result set.</p>
<p><strong>Speed Over Persistance</strong><br />
The reason <a href="<a href="http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/">&#8220;>memcache and MySQL work well</a> as a pair is because they provide the tools needed to have reliable, persistent transactional storage (through MySQL) along with lightning fast data retrieval (through Memcache) especially for rarely-changing results.</p>
<p>Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/' rel='bookmark' title='Memcache as MySQL&#8217;s Hero'>Memcache as MySQL&#8217;s Hero</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/' rel='bookmark' title='Drizzle &#8211; MySQL for the Cloud'>Drizzle &#8211; MySQL for the Cloud</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/08/05/mysql-pulled-mac-os-lion/' rel='bookmark' title='MySQL Pulled From Mac OS X Lion'>MySQL Pulled From Mac OS X Lion</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/04/18/memcache-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How Play Framework Saves the World</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/04/11/play-framework-saves-world/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/04/11/play-framework-saves-world/#comments</comments>
		<pubDate>Mon, 11 Apr 2011 12:46:05 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[internet]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Play Framework]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[play framework]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=367</guid>
		<description><![CDATA[Play framework must be the best-kept secret in the Java world. If you haven&#8217;t had a chance to see their totally awesome demonstration video where they build a full app before your eyes in a matter of minutes, go &#8211; go now. Then come back. Why do I like this framework so much? Put simply, [...]
Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/05/09/accessing-configuration-parameters-play-frameworks-template-engine/' rel='bookmark' title='Accessing Configuration Parameters using Play Framework&#8217;s Template Engine'>Accessing Configuration Parameters using Play Framework&#8217;s Template Engine</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/22/rely-continuous-integration/' rel='bookmark' title='Rely on Continuous Integration'>Rely on Continuous Integration</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Play framework must be the best-kept secret in the Java world. If you haven&#8217;t had a chance to see their totally awesome demonstration video where they build a full app before your eyes in a matter of minutes, <a href="http://www.playframework.org/">go &#8211; go now</a>. Then come back.</p>
<p>Why do I like this framework so much? Put simply, it is an elegant solution for nearly every problem I&#8217;ve ever run into in developing websites, both single-server and multi-server applications. Don&#8217;t take my word for it, see for yourself.</p>
<p><strong>The Goodness of Java</strong><br />
To my mind, Java has the edge over more common scripting languages (like PHP) because it is compiled (fast) and statically typed (reliable). In the past, using compiled languages on the web was only possible if you were using ASP.NET or willing to put up with the hassles of existing Java frameworks and servers.</p>
<p>Play&#8217;s first innovation comes from wrapping the Java runtime inside a Python web server; using a Play application is as easy as running a command line script and connecting with your web browser. Play&#8217;s second innovation is its just-in-time compilation and display of error messages; if you make a mistake you will know in the amount of time it takes to hit refresh on your web browser.</p>
<p>Since it IS java, programmers can use libraries they have built for other applications or sourced from other vendors and plug directly into their code. This is one of the advantages Microsoft has had going for it and it is good to see it implemented so nicely in the open source world.</p>
<p><strong>The Ease of Rails</strong><br />
Love it or hate it, Ruby on Rails has had an affect on the entire web world and its reach is definitely felt in the Play framework. Everything from the routing to JPA integration has that minimal-configuration design that is so prevalent in the Ruby world. Play has the edge though, due to Java annotations and the extra control you get as a developer.</p>
<p><strong>Baked-in Unit Testing</strong><br />
Admittedly this is the first thing that drew me to the Play framework. Unit testing has to be one of the most important aspects of good programming; in fact, if your code is <em>not</em> covered by unit tests, I argue it is incomplete. Play has terrific support for unit testing, functional testing and selenium-based web testing. In version 1.1, Play added a headless web testing mode, paving the way to run framework applications in the context of an automated build environment &#8211; smart move!</p>
<p>Although awkward at first, using YAML files for database fixtures makes a lot of sense. Managing database access in unit tests has always been a challenge but thanks to the in-memory database server and fixture files Play offers us database <em>integration testing</em> &#8211; giving us the fresh-start benefits of mock frameworks along with the soundness of mind that comes from knowing you are testing the real database.</p>
<p><strong>Share Nothing Architecture</strong><br />
Call it laziness, call it human error. At some point in the development cycle, the session always seems to end up carrying user data around. Even with data-sharing applications like memcached, that style of development does not scale well. With Play, sessions are stored in user cookies and consist of an encrypted key. The idea is the application takes care of loading any additional information it needs from this seed information, so the web cluster can be expanded to hundreds of nodes or reduced to a single server with no performance penalties on the other servers. Each Play instance operates as if it is the only one in existence, making it far easier to support complex site architectures.</p>
<p>Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/05/09/accessing-configuration-parameters-play-frameworks-template-engine/' rel='bookmark' title='Accessing Configuration Parameters using Play Framework&#8217;s Template Engine'>Accessing Configuration Parameters using Play Framework&#8217;s Template Engine</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/22/rely-continuous-integration/' rel='bookmark' title='Rely on Continuous Integration'>Rely on Continuous Integration</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/04/11/play-framework-saves-world/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Drizzle &#8211; MySQL for the Cloud</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 02:14:45 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Drizzle]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[Percona]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=356</guid>
		<description><![CDATA[photo credit: nimishgogri Drizzle &#8211; a lightweight fork of MySQL &#8211; has reached general availability. Drizzle&#8217;s design goals are to create a highly performant and module database engine tailored for cloud computing. Some of the interesting features this database has to offer are: No Views, Triggers, or Stored Procedures &#8211; I consider this a huge [...]
Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/08/05/mysql-pulled-mac-os-lion/' rel='bookmark' title='MySQL Pulled From Mac OS X Lion'>MySQL Pulled From Mac OS X Lion</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/18/memcache-mysql/' rel='bookmark' title='Using Memcache with MySQL'>Using Memcache with MySQL</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/' rel='bookmark' title='Memcache as MySQL&#8217;s Hero'>Memcache as MySQL&#8217;s Hero</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class=alignright><a href="http://www.flickr.com/photos/25146185@N04/5162821107/" title="No individual raindrop ever considers itself responsible for the flood" target="_blank"><img src="http://farm5.static.flickr.com/4124/5162821107_312a59bd97_m.jpg" alt="No individual raindrop ever considers itself responsible for the flood" border="0" /></a><br /><small><a href="http://creativecommons.org/licenses/by/2.0/" title="Attribution License" target="_blank"><img src="http://www.alwaysgetbetter.com/blog/wp-content/plugins/photo-dropper/images/cc.png" alt="Creative Commons License" border="0" width="16" height="16" align="absmiddle" /></a> <a href="http://www.photodropper.com/photos/" target="_blank">photo</a> credit: <a href="http://www.flickr.com/photos/25146185@N04/5162821107/" title="nimishgogri" target="_blank">nimishgogri</a></small></div>
<p>Drizzle &#8211; a lightweight fork of MySQL &#8211; has reached general availability. Drizzle&#8217;s design goals are to create a highly performant and module database engine tailored for cloud computing.</p>
<p>Some of the interesting features this database has to offer are:</p>
<ul>
<li><strong>No Views, Triggers, or Stored Procedures</strong> &#8211; I consider this a huge advantage. Stored Procedures were once a good thing when query optimizers were all but non-existant, but modern database systems perform this task extremely efficiently. Using stored procedures adds a second level of APIs to your application for what I would consider to be a rather dubious potential security benefit.</li>
<li><strong>Sharding</strong> &#8211; The client protocol is designed to decide which database server to target based upon a hashing key. This is similar to how memcached handles its linear horizontal scaling &#8211; leaving this calculation to the client is a huge advantage to systems hosting a high number of concurrent visitors</li>
<li><strong>Gearman Support</strong> &#8211; This is a terrific tool for spreading workload across machines. Use Gearman to handle logging in Drizzle, keeping the actual DB server available for database work</li>
</ul>
<p><strong>How Does Drizzle Compare to Percona?</strong><br />
Percona is a high-performance build of MySQL which promises to offer better performance than &#8220;stock&#8221; MySQL. It is built from a branch of publicly-available MySQL source code and enhanced by the folks at Percona. Percona maintains the same functionality as &#8220;real&#8221; MySQL, but attempts to achieve faster speeds.</p>
<p><strong>How Does Drizzle Compare to MariaDB?</strong><br />
MariaDB is a different database engine started by the original creator of MySQL intended to replace MySQL using non-Oracle licensing. Anyone concerned with Oracle&#8217;s development practices or plans for the future of MySQL should consider switching to MariaDB. MariaDB implements all of the existing MySQL functionality plus more and provides a drop-in replacement for MySQL.</p>
<p>Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/08/05/mysql-pulled-mac-os-lion/' rel='bookmark' title='MySQL Pulled From Mac OS X Lion'>MySQL Pulled From Mac OS X Lion</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/18/memcache-mysql/' rel='bookmark' title='Using Memcache with MySQL'>Using Memcache with MySQL</a></li>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/04/10/memcache-mysqls-hero/' rel='bookmark' title='Memcache as MySQL&#8217;s Hero'>Memcache as MySQL&#8217;s Hero</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/03/24/drizzle-mysql-cloud/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Defaulting Null Variables</title>
		<link>http://www.alwaysgetbetter.com/blog/2011/03/04/defaulting-null-variables/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2011/03/04/defaulting-null-variables/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 05:05:15 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[General Programming]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=354</guid>
		<description><![CDATA[One of the things I miss most about C# is the expressive ways in which it handles variable defaults. The &#8216;double ?&#8217; &#8211; ?? &#8211; operator is especially useful for checking whether a value is NULL and providing a default object: No related posts.
No related posts.]]></description>
			<content:encoded><![CDATA[<p>One of the things I miss most about C# is the expressive ways in which it handles variable defaults. The &#8216;double ?&#8217; &#8211; ?? &#8211; operator is especially useful for checking whether a value is NULL and providing a default object:</p>
<p><script src="https://gist.github.com/853983.js?file=Expressive%20NULL%20defaults%20in%20C%23.cs"></script></p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2011/03/04/defaulting-null-variables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Use Rails Generators with MongoDB</title>
		<link>http://www.alwaysgetbetter.com/blog/2010/12/28/rails-generators-mongodb/</link>
		<comments>http://www.alwaysgetbetter.com/blog/2010/12/28/rails-generators-mongodb/#comments</comments>
		<pubDate>Wed, 29 Dec 2010 04:05:55 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.alwaysgetbetter.com/blog/?p=349</guid>
		<description><![CDATA[The MongoDB classes do not come with default generators for Rails applications. In order to use the rails generate commands, you can use the indirect rails3-generators project available at https://github.com/indirect/rails3-generators/#readme Installation: 1. Download the generators into your application&#8217;s lib folder: cd myapp git clone git://github.com/indirect/rails3-generators.git lib/generators 2. Install the rails3-generators gem gem install rails3-generators 3. [...]
Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/03/03/displaying-productiononly-markup-rails/' rel='bookmark' title='Displaying Production-Only Markup in Rails'>Displaying Production-Only Markup in Rails</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The MongoDB classes do not come with default generators for Rails applications. In order to use the rails generate commands, you can use the indirect rails3-generators project available at https://github.com/indirect/rails3-generators/#readme</p>
<p>Installation:<br />
1. Download the generators into your application&#8217;s lib folder:<br />
<code>cd myapp<br />
git clone git://github.com/indirect/rails3-generators.git lib/generators</code></p>
<p>2. Install the rails3-generators gem<br />
<code>gem install rails3-generators</code></p>
<p>3. Add this to your project&#8217;s Gemfile<br />
<code>gem 'rails3-generators'</code></p>
<p>Usage:<br />
<code>rails generate model ModelName --orm=mongo_mapper</code></p>
<p>Related posts:<ol>
<li><a href='http://www.alwaysgetbetter.com/blog/2011/03/03/displaying-productiononly-markup-rails/' rel='bookmark' title='Displaying Production-Only Markup in Rails'>Displaying Production-Only Markup in Rails</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alwaysgetbetter.com/blog/2010/12/28/rails-generators-mongodb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Served from: alwaysgetbetter.com @ 2012-02-07 18:03:12 -->
