<?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>Justin Carmony &#187; scaling</title>
	<atom:link href="http://www.justincarmony.com/blog/tag/scaling/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.justincarmony.com/blog</link>
	<description>Web Designer &#38; Software Engineer</description>
	<lastBuildDate>Wed, 01 Feb 2012 04:30:16 +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>Working with Middle-Scale Websites</title>
		<link>http://www.justincarmony.com/blog/2011/07/18/working-with-middle-scale-websites/</link>
		<comments>http://www.justincarmony.com/blog/2011/07/18/working-with-middle-scale-websites/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 00:02:40 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[middle-scale]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[system administration]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=940</guid>
		<description><![CDATA[I&#8217;ve been thinking about this idea for awhile, and I thought I would put a name to the thought. I brought up this idea while I was giving my &#8220;Real Life Scaling&#8221; presentation at the Utah Open Source Conference in 2009. Here is the problem I think most individuals in the web development face: Hopefully ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/04/18/data-backups-there-are-no-excuses/' rel='bookmark' title='Data Backups &#8211; There Are No Excuses'>Data Backups &#8211; There Are No Excuses</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/16/speaking-utah-open-source-conference-2009/' rel='bookmark' title='Speaking: Utah Open Source Conference 2009'>Speaking: Utah Open Source Conference 2009</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/' rel='bookmark' title='Presentation: Real Life Scaling'>Presentation: Real Life Scaling</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking about this idea for awhile, and I thought I would put a name to the thought. I brought up this idea while I was giving my &#8220;Real Life Scaling&#8221; presentation at the Utah Open Source Conference in 2009. Here is the problem I think most individuals in the web development face:</p>
<p>Hopefully at some point, your website gets a lot of traffic. Yay, you&#8217;ve reached your goal of getting good traffic, but it is soon followed by issues with performance and load. I like to call these the growing pains of a website. So as a web developer, I suddenly have the epiphany of &#8220;Hey, I need to scale my website!&#8221; What follows next is the biggest mistake a web developer can make:</p>
<p>They start looking at articles on how Google scales, or maybe how Facebook manages all of their traffic.</p>
<p><strong>This is a mistake!</strong> To be brutally honest, you are <strong>not</strong> Google. You are not Facebook. You are not Twitter. You are a website that receives less than 0.000001% of the traffic that some major websites receive.</p>
<p>Why is this dangerous for web developers to do? Google, Twitter, Facebook, and others like them are solving complicated at a very large scale. I remember a presentation by a Twitter engineer who developed a program for a unique ID generator that can generate millions of IDs per second. The probability of you needing this type of solution is about the same as being struck by lightening. Applying these same practices at a much smaller scale are not realistic. If a locally owned grocery store wanted to open a second store, they would not adopt the same practices that Wal-mart use to manage their 8970 stores.</p>
<h2>A Little Reality Check</h2>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/StackExchange.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/StackExchange.png" alt="" title="StackExchange" width="300" height="80" class="alignnone size-full wp-image-941" /></a></p>
<p>I&#8217;m sure that most of my readers know of <a href="http://stackexchange.com/">StackExchange.com</a>. They power the popular website <a href="http://stackoverflow.com/">StackOverflow</a> and <a href="http://stackexchange.com/sites">several others</a>. They have about two million visitors per day. That is a <em>lot</em> of traffic. StackOverflow is ranked #123 on Alexa. So you would imagine that they have a very large infrastructure serving all of this traffic?</p>
<p>Earlier this year, Stack Exchange wrote <a href="http://blog.serverfault.com/post/stack-exchanges-architecture-in-bullet-points/">an article about their production environment</a>. I was surprised on what exactly they were using. In paticular, the number of Production Servers*:</p>
<blockquote><ul>
<li>12 Web Servers (Windows Server 2008 R2)</li>
<li>2 Database Servers (Windows Server 2008 R2 and SQL Server 2008 R2)</li>
<li>2 Load Balancers (Ubuntu Server and HAProxy)</li>
<li>2 Caching Servers (Redis on CentOS)</li>
<li>1 Router / Firewall (Ubuntu Server)</li>
<li>3 DNS Servers (Bind on CentOS)</li>
</ul>
</blockquote>
<p>That is 22 servers for 2 Million Visits per day, serving 800 HTTP requests per second. Now, StackExchange did clarify that they did have other servers for management and fail over, but 22 servers handle their production load. This is a website that is ranked the 123rd most visited website in the world.</p>
<p>Honestly, most websites could be run on half a dozen servers if designed and configured correctly, including redundancy. Some really busy websites could run off a dozen servers. Unless you&#8217;re in the top 5,000 websites on the web, you really shouldn&#8217;t be worried about large-scale techniques. </p>
<p>So when you&#8217;re website is starting to grow, and you leave small scale, you&#8217;ll enter the phase of &#8220;Middle-Scale.&#8221;</p>
<h2>What is Middle-Scale?</h2>
<p>Middle-Scale is like being an awkward teenager:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/cera-awkward.jpeg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/cera-awkward-300x200.jpg" alt="" title="cera-awkward" width="300" height="200" class="alignnone size-medium wp-image-942" /></a></p>
<p>You know that you can&#8217;t be the only one suffering through this, but you&#8217;re unsure how to proceed. It feels like you&#8217;re missing missing out on things everyone else must already know, but aren&#8217;t talking about. Like everyone else are awesome vampires or something:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/twilight-cast.jpeg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/twilight-cast-300x225.jpg" alt="" title="twilight-cast" width="300" height="225" class="alignnone size-medium wp-image-943" /></a></p>
<p>But the reality is this: they don&#8217;t have some awesome secret! They are just normal teenagers.</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/teenage-friends.jpeg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/07/teenage-friends-300x200.jpg" alt="" title="teenage-friends" width="300" height="200" class="alignnone size-medium wp-image-944" /></a></p>
<p>This same idea applies to Middle-Scale websites.</p>
<p>Middle-Scale is when the <strong>most important things are <em>still</em> the best practices</strong>. Only now when you deviate from them you can feel those consequences. When you only had 100 users, a couple of nested queries and missing indexes didn&#8217;t cause that much of a problem. Your database is powerful enough to hide the inefficiencies. However, when you get to 10,000 users, your database can no longer hide the inefficiencies.</p>
<p>Middle-Scale is when simply separating your web server and database server isn&#8217;t enough. You&#8217;ll probably need to add some sort of cache like <a href="http://www.justincarmony.com/blog/2009/06/24/writing-effictive-php-caches-with-memcached/">memcached</a>. You&#8217;ll need to start tweaking your MySQL, Apache, and PHP configurations. </p>
<p>Then, after you&#8217;ve ironed out your inefficiencies, you&#8217;ll start to use multiple servers. You&#8217;ll probably add a Load Balancer with multiple web servers. After that, you&#8217;ll probably have some sort of Master-Slave replication for your Database for backups and fail-overs.</p>
<p>You start to leave this &#8220;Middle-Scale&#8221; classification when you move to multiple data centers, and start to do some load balancing at the the DNS layer. This is when you&#8217;ll start to have a dedicated sys-admin team.</p>
<h2>Okay, I&#8217;m Middle-Scale! So what should I do? Where do I look?</h2>
<p>First off, you <strong>must adhere to best practices.</strong> If you are working with PHP, research PHP performance and best practices. Do they same for each of your technologies, like Apache and MySQL. You will need to stop treating your application as one big app, and start to understand all of it&#8217;s moving parts.</p>
<p>Second, you <strong>must understand your specific problems.</strong> Scaling ins&#8217;t a problem, nor is it a solution. It is a generic term for many different types of solutions. Without understanding why your website is running slow, or why it cannot handle the load, you will not be able to create an effective solution.</p>
<p>So you don&#8217;t have a scaling problem. You have a MySQL performance issue, or a Apache problem, or a PHP problem. Most likely, it is something extremely specific. You have a high volume of MySQL write operations (i.e. UPDATE, INSERT, DELETE, REPLACE), or perhaps you are missing some indexes and have too many full table scans. </p>
<p>Third, Googling for help will only get you so far. You are starting to enter a phase when it is harder and harder to find answers to your broad issues. Talking with other experienced people who have gone through the Middle-Scale pains before will help immensely. <a href="http://www.justincarmony.com/blog/2009/11/27/my-php-user-group-experience/">I cannot recommend highly enough going to User groups</a>. Being able to communicate with someone, either face to face, on the Phone, over IRC, etc. is invaluable. While I&#8217;ve learned a lot at conference and usergroup presentations, I&#8217;ve learned even more by just talking with the people attending and at the social gatherings.</p>
<h2>Profile &#038; Performance will Naturally Lead to Scaling</h2>
<p>When you want to scale, it can feel like a very daunting task. It seems like this big unknown complicated solution. What in the world am I going to do? I remember feeling these worries when I first started to investigate load balancing and sharding for some websites I was working on.</p>
<p>The thing is, if you start to profile your application, you will discover it&#8217;s inefficiencies. I remember when I spent a sold week, working 12-16 hours a day profiling and optimizing Dating DNA&#8217;s database. I found a lot of bad queries, and I was able to cut our load times from 2-5 seconds to under 0.1 seconds. The CPU on the database server went from 80-90% CPU utilization to under 10%. It was incredible, and then I promptly took the entire next week off. When we migrated to new servers, I was able to move to less powerful database server and still have the same great performance. So by profiling and optimizing our database, I didn&#8217;t need to worry about spinning up multiple master databases and sharding our data.</p>
<p>With Clipish, we faced almost opposite scaling problems. The database was rarely an issue, but our web server CPU&#8217;s were. We do a lot of ImageMagick manipulations of images, and at high volumes on virtual servers this can be a big issue. So over the last year we&#8217;ve introduced some load balancing and CDN tools to help serve all 10 TB of bandwidth for Clipish.</p>
<p>The thing is, when you start to profile your application, you start to understand it&#8217;s low areas better, so you have a much better idea on what do to. Even if you don&#8217;t know your solution, it is much easier to find a solution with a sound understanding of the problem. For example &#8220;scaling mysql&#8221; yields much less helpful results than &#8220;mysql full table scans&#8221; in Google.</p>
<h2>So should I ignore what Facebook and Google do for scaling?</h2>
<p>Of course not! First off, they do cool stuff. Just because I&#8217;ll watch NASA launch a space shuttle doesn&#8217;t mean I&#8217;ll try to make a rocket system for my broken lawn mower. But you have to put what they are doing into context. People from large websites have published several good &#8220;best practices&#8221; articles on techniques that help any website. Especially things on the client/browser side of things. Just use caution. I cringe when I hear someone say &#8220;we&#8217;re trying to use Cassandra to solve XYZ problem at work&#8221; when it is severe overkill. </p>
<h2>Final Thoughts</h2>
<p>Most of the time when I talk about performance and scaling with other people, it is when they are in &#8220;critical mode.&#8221; Their website is down, slow, unusable, etc, and they are looking to fix the problem. I will say, it is much more difficult to profile in &#8220;critical mode&#8221; than profiling before hand. The reason is you are much more desperately focused on getting it working again instead of understanding the problem. </p>
<p>I&#8217;ll be giving a presentation this Thursday at UPHPU on Profiling PHP Applications. I&#8217;ll post the slides, and most likely write some articles on the subject afterwards. As always, feel free to email me or leave a comment.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/04/18/data-backups-there-are-no-excuses/' rel='bookmark' title='Data Backups &#8211; There Are No Excuses'>Data Backups &#8211; There Are No Excuses</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/16/speaking-utah-open-source-conference-2009/' rel='bookmark' title='Speaking: Utah Open Source Conference 2009'>Speaking: Utah Open Source Conference 2009</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/' rel='bookmark' title='Presentation: Real Life Scaling'>Presentation: Real Life Scaling</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/07/18/working-with-middle-scale-websites/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>MySQL, Redis, and a Billion Rows &#8211; A Love Story</title>
		<link>http://www.justincarmony.com/blog/2011/05/23/mysql-redis-and-a-billion-rows-a-love-story/</link>
		<comments>http://www.justincarmony.com/blog/2011/05/23/mysql-redis-and-a-billion-rows-a-love-story/#comments</comments>
		<pubDate>Mon, 23 May 2011 15:20:35 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Dating DNA]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[scaling]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=923</guid>
		<description><![CDATA[This last week we pushed live a very large architecture change for Dating DNA. For those who know me, and have heard me talk about the Dating DNA Scoring System, they know how big of a problem we faced. For those who don&#8217;t know, let me give some background: The Problem With Dating DNA, our ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/04/06/restoring-large-mysql-dump-900-million-rows/' rel='bookmark' title='Restoring Large MySQL Dump &#8211; 900 Million Rows'>Restoring Large MySQL Dump &#8211; 900 Million Rows</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This last week we pushed live a very large architecture change for <a href="http://www.datingdna.com/">Dating DNA</a>. For those who know me, and have heard me talk about the Dating DNA Scoring System, they know how big of a problem we faced. For those who don&#8217;t know, let me give some background:</p>
<h3>The Problem</h3>
<p>With Dating DNA, our goal was to display a compatibility score with <strong>every other user</strong>. This score is generated by taking two sets of answers to our 20 page survey, and running it through our algorithm. While it is super convenient for our users, this poses a problem. We wanted not only for people to be able to visit a profile and see a score, which is easy to generate a score on demand. We wanted our users to be able to <strong>browse</strong> other profiles sorted <strong>by</strong> their score with them. This requires us to <strong>pre-generate</strong> and <strong>store</strong> these scores, and then later query them.</p>
<p>So Ultimately, in theory, our &#8220;scores&#8221; data scaled at the following rate, with X as the number of registered users: </p>
<h3>X^2 &#8211; X</h3>
<p>That is at an exponential rate, which is practically impossible to scale at. The very first version of Dating DNA (before I took over the project) had about 1,500 users. The scores were stored in a single table. Every night, a &#8220;cron job&#8221; would run and get a list of every user, and loop through every possible iteration and re-generate each score. At 1,500 users that was 2,248,500 records. That is a <strong>lot</strong> for just 1,500 users. With our current user count, we would roughly have 359,999,400,000 score records. Thats <strong>359 Billion</strong> records if you don&#8217;t want to count the commas. </p>
<p>This old system of daily cron jobs broke at about 2,000 users. We would have problems with the cron job taking over 48 hours to complete, and would end up with 3 scripts running at the say time. One for today, one for yesterday, and one for the day before that.</p>
<h3>Smart Logic &#038; Threading</h3>
<p>We solved our first problem by using some common sense and smart logic. I won&#8217;t detail the lengthy measures we go through, but we can basically boil down our entire user base to an estimated top 5000 matches for any given user. If we have a heterosexual man named Joe, he doesn&#8217;t care about the hundreds of thousands of other heterosexual men who he scores a 2 or 3 with, but the heterosexual women he scores above a 6 with. So we don&#8217;t store the score for Frank, Jimmy, and Alan with Joe, but Sally, Rachael, and Tiffany. </p>
<p>The second part we solved was pre-generating scores for a user. After a User has reached a point in the survey where we have all the information we need to generate scores, and they are just filling in some miscellaneous, we put them in a queue. We then have a server process than is continuously running checking this queue, and spinning off multiple generation &#8220;threads&#8221; that crunch the data and store the score. We&#8217;ve spent a lot of time perfecting this system. Currently we typically can generate any given user&#8217;s matches in roughly 5 to 20 seconds, depending on how busy our website is. </p>
<h3>Storing The Score in MySQL</h3>
<p>The problem we now faced was the write through put of MySQL. Even through sharding and partitioning, we wanted to have a goal of sustaining 1,000 registrations per minute in a scalable and high performance manner. Which comes down to about 83,000 records per second that are either being inserted or updated. We then needed to be able to retrieve large volumes of scores just as fast.</p>
<p>I believe we could have bent MySQL to our will and got it to work, but it would be at a high cost of server power, and that cost wouldn&#8217;t scale well with our revenue stream. After we moved from the MySQL storage of the scores, I ran a query to see how many scores we were indeed storing. The final total was 950,363,992. Just 50 Million shy of one billion. It took 1 hour 49 min 38.27 sec to calculate that count. It is evidence that even though MySQL wasn&#8217;t the best choice for storing this data, it did it pretty well considering this single table was holding 90 times more data than any other table.</p>
<h3>Picking Another Solution</h3>
<p>In 2009 we started to throw around ideas for a new scoring system. I cannot stress enough when talking to others about &#8220;NoSQL&#8221; solutions the best solution for any given job is based on your data&#8217;s <strong>characteristics</strong>. User registration data needs to be treated differently than activity logging and basic stats. It might be okay to lose a few minutes of activity logging (depending on the app), but you definitely don&#8217;t want to be losing user accounts.</p>
<p>With Dating DNA&#8217;s scores, we had one great advantage. The data could be somewhat volatile, because we can always re-generate a set of matches for any given users. Of course, we didn&#8217;t want to lose <strong>all</strong> of it, because having to regenerate everyone&#8217;s scores is a major pain and extremely resource intensive. But if we lost a few minutes, anything lost could easily be regenerated. So when we started research for a solution, we were willing to sacrifice some persistance for performance. We wouldn&#8217;t be doing the same for our user registration data.</p>
<p>At first, I was contemplating building a completely in-house project to handle the data storage and retrieval of the scores. It would be a lot of work, and decided against. So I then thought about hacking together a custom solution with memcached. The idea would be a user&#8217;s set of matches would be stores in a variable in memcached. So the website and generation scripts would interface with memcached, and a server process would write inactive sets of scores (people who weren&#8217;t logged in) to a file on the disk. When they logged it and scores were being pulled and stored for that user, it would load the data from disk into memcached.</p>
<p>While the general concept was sound, the actual execution would be difficult. Memcached only supported strings for values, and we would still need some sort of database to manage which users had the data in memory vs disk, and the server process (probably just a php, python, or node.js script running continuously) would have to be running constantly, and if that broke things could get messy.</p>
<p>It boiled down too many points of failure and complexity. But it was a step in the right direction, so we kept looking for a better solution.</p>
<h3>Redis, the Advanced Key-Store</h3>
<p>I was talking with <a href="http://josephscott.org/">Joseph Scott</a>, an employee of <a href="http://automattic.com/">Automattic</a> as a Bug Exorcist (not joking, <a href="http://automattic.com/about/">his real title</a>), and he mentioned I should look into <a href="http://redis.io/">Redis</a>. He gave me a brief overview of what it was, and I shuffled that info back in my brain. I can&#8217;t remember how much longer it was before I checked out and compiled a copy of Redis, but I quickly discovered it could be a viable storage system for our scores.</p>
<p>So I spun up a virtual machine, installed Redis, and started to pound away at it. One of the things I wanted to test was the new feature (at the time) of Virtual Memory for redis. What this allowed was for Redis to make it&#8217;s own Virtual Memory on the server and store the lest recently used data to disk. When a Redis object was retrieved and it was in the VM, it would swap it back into memory, and swap older data to disk. This was just like the idea I had before with using an archaic system with memcached, but much more elegant.</p>
<p>The second thing was Redis&#8217;s support for multiple data types. So instead of having a json encoded string that held the scores and user ids for another user, we could have a hashtable or even a sorted set. It was a much more elegant solution than what we were thinking of before.</p>
<h3>Some Limitations to Redis</h3>
<p>However, there were a few limitations that we faced when implementing Redis. Redis works flawlessly with smaller sets of data. But the larger your data set, the more careful and aware you need to be about a few things that will kill your redis instance.</p>
<p>First off, with memcached, if you set a memory limit, it is a hard limit. I&#8217;ve never seen memcached use more memory than what you allow it to use. Redis, on the other hand, has soft memory limits. This is because of the way the Background Saves work so you can have persistant data. When a Background Save is issued, Redis will fork itself, and have one thread save a snapshot to the disk, and the other thread will continue to operate. In order to do this, Redis will exceed the standard memory limits, and your memory usage will go up much quicker. Once the background save is complete, it will close the forked backup process and sync the memory back to one data set. (I&#8217;m not a computer science guy, nor do I know a lot of lower level programming, so I might be describing this not 100% accurate, but this is how I envision it in my head). </p>
<p>Now, if you are not using the Virtual Memory, this isn&#8217;t that bad. However, when using Virtual Memory, the Background Saves take a great deal longer (from seconds to almost a minute or so), which isn&#8217;t too bad, but there is a catch. You will not be able to swap to the VM Disk until after the BG Save. This means that all Redis objects swaped to memory will stay in memory until after the BG Save is complete. This is because, like the memory from the fork, the Virtual Memory file is being used for the BG Save instead of the process handling requests.</p>
<p>So the one limitation we&#8217;ve encountered is we cannot run scripts that &#8220;query&#8221; large amounts of data from Redis. For example, it would be very simple to get a listing of users using the KEYS command, and then loop through the values using a HLEN to read the length. This will cause you to swap from and to the virtual memory a great deal. If a Background Save is occuring, Redis will not swap to disk until the BG Save is complete. This means if you have 10 GB of data in Virtual Memory, and you have a 1 GB instance of Redis, you will suddenly be reading gigs of data into Redis&#8217;s memory. If you are on a 2GB machine, you can easily use up all the memory on the server and then start using the System&#8217;s Swap.</p>
<p><strong>Once you start using the Operating System&#8217;s Virtual Memory, it is game over.</strong> Your Redis instance&#8217;s performance will tank, and your Background Save might not finish, and you will need to restart redis. </p>
<p>There are some ways to give Redis a &#8220;Hard&#8221; limit on memory, but we opted to configure our servers in a way that doesn&#8217;t require this. If Redis hits the memory limit, it can start throwing write operation errors, which we didn&#8217;t want.</p>
<h3>How We Configure Redis</h3>
<p>After much trial and error and testing internally, we believe we found a sweet spot. We deploy a redis server, and spin up three redis instances on a different port each. Each is configured with 4 GB of Virtual Memory using 4096 size pages, and only 256 MB of &#8220;memory&#8221; using the vm-max-memory setting. While you would think this would mean a hard limit, it is a soft limit, and more of a goal &#8220;we&#8217;ll try to only use 256 MB of memory to store the data, if we&#8217;ll exceed it if needed.&#8221; Given our patterns of usage, Redis&#8217;s actually usage fluctuates (based on ps aux&#8217;s reporting) between 640 MB to 1100 MB of RAM, depending on if a background save is being executed or not. Redis is configured to perform background saves every 10 minutes, which take about a minute to perform.</p>
<p>So between the other admin services running on the box, and the three redis instances, we use just over 3GB RAM:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/05/redis-instance-memory.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/05/redis-instance-memory.jpg" alt="" title="redis-instance-memory" width="602" height="230" class="alignnone size-full wp-image-926" /></a></p>
<p>The amount of CPU required is extremely low, and almost 100% from writing the background saves to the disk:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/05/redis-cpu.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/05/redis-cpu.jpg" alt="" title="redis-cpu" width="601" height="229" class="alignnone size-full wp-image-927" /></a></p>
<p>So what do we get in return? We estimate each instance with 256 MB of data can hold roughly 2,000 active users. So with a single server we can support 6,000 users online at any given moment. We can store the scores for roughly 360,000 users on a single 4 GB box, which is about 1.8 Billion scores. Then, if we need more, we just provision another box, and our system will start assigning users to the instances on that machine.</p>
<p>Because of our ability to re-generate the scores, we decided to only convert the users who had logged in the past three months to the new system. If a user who hadn&#8217;t logged in since then logged in again, it would in the background assign them to a redis instance and rebuild their matches for them.</p>
<h3>Using Redis with PHP</h3>
<p>I recommend currently to use the PHP Redis client <a href="https://github.com/nrk/predis">predis</a>. I&#8217;ve used others like <a href="http://rediska.geometria-lab.net/">Rediska</a>, but I prefer the straight forward approach of predis.  </p>
<p>A high level view of how we use Redis with our PHP based website is we have a class called RedisManager than manages pretty much all the connections to Redis. It supports lazy connections (which is important to us, since we don&#8217;t want to have to connect to every instance of Redis we have), and I hope to open source it some day soon.</p>
<p>One key performance trick we&#8217;ve noticed is to use Pipelining to the redis instance. We don&#8217;t use this so much on the website, but our score generation &#8220;threads.&#8221; Writing thousands of scores one by one eats up a lot of network overhead versus sending them in batches (we send in batched of 500 or 1000, depending on the situation). Using pipelining is extremely fast for us, and I highly recommend it for any large batch of commands.</p>
<h3>Using Redis Elsewhere in Dating DNA</h3>
<p>Now, it might seem that we&#8217;ve put a lot of thought and effort into using Redis, and I want to make sure it was understood that Redis itself wasn&#8217;t difficult to use, but the volume of data were were dealing with. On Dating DNA, we also use Redis to power out in-app chat system (which I&#8217;ve <a href="http://www.justincarmony.com/blog/2011/01/07/creating-chatroom-walls-with-redis-and-php/">written about previously</a>), and it works great and is currently only using 146.70 MB of RAM, and serves thousands of requests per second.</p>
<h3>The Future</h3>
<p>I still have a lot of great ideas for Redis and Dating DNA, both with the score system, and outside of it. I plan on writing several reporting tools for Redis and hope to share them on github. I am currently working on the code and scripts for automatic deployment for Redis servers for Dating DNA, so we can scale easily with the push of a button. I&#8217;m excited for the work that is being done on Redis, and highly recommend it to anyone.</p>
<p>If there are details you would like to know more about, leave a comment and I&#8217;ll try to answer them. If you see me at tek11, feel free to ask me about this, and I can show you in detail how it works (internet permitting).</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/04/06/restoring-large-mysql-dump-900-million-rows/' rel='bookmark' title='Restoring Large MySQL Dump &#8211; 900 Million Rows'>Restoring Large MySQL Dump &#8211; 900 Million Rows</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/05/23/mysql-redis-and-a-billion-rows-a-love-story/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How I Became a Web Developer &amp; CTO</title>
		<link>http://www.justincarmony.com/blog/2011/02/23/how-i-became-a-web-developer-cto/</link>
		<comments>http://www.justincarmony.com/blog/2011/02/23/how-i-became-a-web-developer-cto/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 11:57:56 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[ASP .NET]]></category>
		<category><![CDATA[cevo]]></category>
		<category><![CDATA[clipish]]></category>
		<category><![CDATA[cto]]></category>
		<category><![CDATA[Dating DNA]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[kiosks]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=763</guid>
		<description><![CDATA[Note: many of the screenshots of websites I had done in the past are from the Internet Archive and many of the images are missing. But it can give an idea on the projects I had worked on. One day I&#8217;ll try and track down the original files and update the screenshots. Today some memories ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/09/14/so-you-want-to-be-a-web-developer/' rel='bookmark' title='So You Want To Be A Web Developer?'>So You Want To Be A Web Developer?</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/15/web-development-10-years-ago-now/' rel='bookmark' title='Web Development 10-Years Ago &amp; Now'>Web Development 10-Years Ago &#038; Now</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/15/being-a-productive-developer/' rel='bookmark' title='Being a Productive Developer'>Being a Productive Developer</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><em>Note: many of the screenshots of websites I had done in the past are from the <a href="http://www.archive.org/web/web.php">Internet Archive</a> and many of the images are missing. But it can give an idea on the projects I had worked on. One day I&#8217;ll try and track down the original files and update the screenshots.</em></p>
<p>Today some memories came from when I first started with web development. So before I forget anymore of the details, I thought I would share my <em>unique</em> way I became a web developer. I never went to school to learn Computer Science or Information Systems. I&#8217;ve had a total of 2 programming classes, which were my in sophomore and junior years of High School, one of which we lovingly nicknamed Warcraft 101, because we would spend the entire time getting out butts kicked in <a href="http://en.wikipedia.org/wiki/Warcraft_II:_Tides_of_Darkness">Warcraft 2</a> by my classmate Daren (We all got A&#8217;s, we had just finished the entire coursework in 2 and a half weeks). </p>
<p>The reason I share this is perhaps others who hope to become a web developer can learn some of the valuable lessons I picked up along the way. That, and that my close programming friends and colleagues can get a kick out of my humble roots.</p>
<h3>Heritage</h3>
<p><span id="more-763"></span></p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/photoshop3.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/photoshop3-150x150.png" alt="Photoshop 3" title="photoshop 3" width="150" height="150" class="alignright size-thumbnail wp-image-764" /></a>How I ended up in Technology to begin with is probably because part of it is in my blood. My Father, <a href="http://kevincarmony.com/kcprofessional.htm">Kevin Carmony</a>, has been the owner of several technology businesses. So I was exposed frequently to computers and other technologies my whole life. I remember some time when I was about five or six, in the late 1980s, playing against my younger brother on a multiplayer ASCII LAN game at the old Streamlined Information Systems office. It was wandering around a 2D maze hunting these 8-bit monsters, and each other, and it was amazing fun. </p>
<p>I also had access to a lot of expensive software that were hand-me-downs. One of them I remember is Photoshop 3 and 4, spending hours trying to design websites with it. To give you an idea how old that is, the current version is CS5 (aka version 12). The first program I really used to make a website was (and get ready to gasp) <a href="http://en.wikipedia.org/wiki/Microsoft_FrontPage">Microsoft FrontPage</a> in 1997. There were also a couple of website books laying around that I would read, or at least try to.</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/visual_studio_6.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/visual_studio_6-150x150.jpg" alt="" title="visual_studio_6" width="150" height="150" class="alignright size-thumbnail wp-image-785" /></a>On the other side of the equation was my mother, while herself wasn&#8217;t extremely technical, encouraged and &#8220;sponsored&#8221; my learning when I was young. By sponsoring I mean she many times bought computers, digital piano keyboards, DSL (we were some of the very first people to have &#8220;high&#8221; speed internet in our town), and paid for many other expenses. I remember a several hundred dollar long distance bill because I would call the &#8220;Provo&#8221; dial-up connection instead of the broken &#8220;Ogden&#8221; phone number. I even once ordered a &#8220;temporary&#8221; AOL dial-up account, with her credit card and <strong>without</strong> permission, because our ISP was down, and I needed to check my website. I forgot to cancel it afterward, and it racked up a few months of fees before my mother realized what had happened. She never yelled or mad over these &#8220;expenses&#8221;, that I realize now as an adult, were not cheap. She just told me in the future what to do to avoid causing them again.</p>
<p>She was also very patient with a son whose grades weren&#8217;t the best, and who would rather work on a website than do his homework. I know if she would have came down hard on me, my GPA would probably be higher (its wasn&#8217;t bad, just not great), but I wouldn&#8217;t have learned what I did, <strong>nor make the connections that eventually fast tracked my career</strong>. I owe her a great deal (I love you mom!)</p>
<h3>Humble Beginnings</h3>
<p>I first learned about websites, and how <strong>I</strong> could make them, while sitting in my 7th Grade Band Class. My fellow clarinet player Kenny Cottrell explained to me in between songs about <a href="http://en.wikipedia.org/wiki/HTML">HTML</a>, <a href="http://en.wikipedia.org/wiki/Notepad_%28software%29">Notepad</a>, and how I could learn to make my own website. So I set off to learn HTML. In my excitement, I found an online book on HTML, and printed the entire 400 page book on my mother&#8217;s home printer. Single page, of course, because I couldn&#8217;t figure out how to easily do double page, and it was on her expensive laser printer (this was 1997) with expensive cartridges. </p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/amazon1999.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/amazon1999-150x150.png" alt="Amazon in 1999" title="Amazon in 1999" width="150" height="150" class="alignright size-thumbnail wp-image-765" /></a>My very first website was hosted on one of my father&#8217;s web servers, and using FrontPage, I made a website about a game called <a href="http://en.wikipedia.org/wiki/The_Realm_Online">The Realm</a>, one of the very first graphical Massive Multiplayer Online games (MMO, think World of Warcraft). It was bad, really bad. I can&#8217;t find any pictures or old files from it, but you can take my word for it. When spending weekends at my Grandma&#8217;s house with my Dad, I would spend hours designing and writing websites, or at least try to. They were all bad, but I learned a lot by trying over and over again. I would design a site, look a a professional site, and try to see why mine stunk while the professional ones were so much nicer. I remember looking at <a href="http://www.amazon.com/">Amazon</a>&#8216;s rounded corner tabs for <strong>hours</strong> trying to get mine to look just as nice.</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/granstre_screen018.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/granstre_screen018-150x150.jpg" alt="The Granstream Saga for PSX" title="The Granstream Saga for PSX" width="150" height="150" class="alignright size-thumbnail wp-image-768" /></a>I then got my first domain, RPGLegacy.com, in 1998 and started a website with game reviews and walkthroughs for PlayStation RPG games. I remember writing reviews and information for games like <a href="http://en.wikipedia.org/wiki/Final_Fantasy_VII">Final Fantasy VII</a>, <a href="http://en.wikipedia.org/wiki/Suikoden_%28video_game%29">Suikoden I</a> &#038; <a href="http://en.wikipedia.org/wiki/Suikoden_II">II</a>, and even more obscure (and terrible) titles like <a href="http://en.wikipedia.org/wiki/The_Granstream_Saga">The Granstream Saga</a>. I started to get perhaps 100 visitors a month, and I thought that was great. I even got emails from people asking me for help. One subject in particular was in <a href="http://en.wikipedia.org/wiki/Breath_of_Fire_III">Breath of Fire 3</a> dozens had emailed me about getting stuck in a castle. I myself had gotten stuck in the same place for hours, and posted an in-depth solution for finding Honey the Robot in the castle. For being a 15 year old kid in junior high, it was a lot of fun, and I learned a lot. I had moved to Dreamweaver for making the website, and the designs weren&#8217;t half bad. However, I don&#8217;t have a screenshot of how the old site used to look.</p>
<h3>Counter-Hack</h3>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/CSS_Hacked.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/CSS_Hacked-150x150.jpg" alt="Counter-Strike Source Hack" title="Counter-Strike Source Hack" width="150" height="150" class="alignright size-thumbnail wp-image-770" /></a>I was 16 and I in high school. My classmate Daren (the same who whooped me at Warcraft 2) introduced me to a game called <a href="http://en.wikipedia.org/wiki/Counter-Strike">Counter-Strike</a>. It was a <a href="http://en.wikipedia.org/wiki/First-person_shooter">First Person Shooter</a>, and it was a lot of fun. However, at the same time, there were a lot of these &#8220;cheats&#8221; and &#8220;hacks&#8221; programs that were coming out. My friends and I would be accused of &#8220;cheating&#8221; and &#8220;hacking&#8221; when in reality we weren&#8217;t. Also, some of the claims on how we were cheating were rather absurd. So I started to investigate the truth and fiction behind these programs. I learned a lot, and thought I would share that knowledge, so I started Counter-Hack (http://www.counter-hack.net) in the summer of 2001.</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/counterhack-v1.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/counterhack-v1-150x150.png" alt="Very First Version of Counter-Hack" title="Very First Version of Counter-Hack" width="150" height="150" class="alignright size-thumbnail wp-image-780" /></a>Little did I know how extremely popular this website would become. Within a week or two I had a website wtih decent content up using Dreamweaver. This was 100% HTML based, no CSS, trying to use Dreamweaver&#8217;s Template system. What I would have given for some PHP or even WordPress. While with RPGLegacy, I had maybe a max of 5,000 visitors over it&#8217;s entire lifespan, within a month I had 30,000 visitors to Counter-Hack. Soon I was getting thousands of visitors per day. About the same time I met <a href="http://www.anthonyro.com/">Anthony Ouwehand</a> (nicknamed H3X), who had ran another popular website about video game hacks. He graciously helped me with his PHP/MySQL skills. He designed, and developed, the Counter-Hack website that was launched in 2002 and ran until 2008 when everyone involved with the project just were too busy, and the site had ran it&#8217;s course and purpose. Two years of that time the project ran with the rest of the volunteers while I served an LDS Mission in Torreon Mexico. </p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/Capture.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/Capture-150x150.png" alt="Counter Hack Version 3 by Anthony" title="Counter Hack Version 3 by Anthony" width="150" height="150" class="alignright size-thumbnail wp-image-782" /></a>During the years with Counter-Hack, a few highlights were interviews with Wired for news stories, working with Valve Software to help recover the <a href="http://en.wikipedia.org/wiki/Half-Life_2#Leak">HL2 Leak</a>, and an interview and article with Rolling Stone Magazine. During it&#8217;s height, Counter-Hack was covering dozens of games with hundreds of thousands of visitors a month. During it&#8217;s later years, Counter-Hack implemented a Wiki system for much of it&#8217;s content, something that was pretty new at the time. All and all, it was a great experience with dozens of volunteers and great memories. For a hobby during High School and the year after graduating, I couldn&#8217;t have asked for a better experience. I learned a lot before even starting college.</p>
<h3>Developing Out of Necessity for CEVO</h3>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-v1.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-v1-150x150.jpg" alt="CEVO Version 1" title="CEVO Version 1" width="150" height="150" class="alignright size-thumbnail wp-image-774" /></a>The reason why for the background story is for two reasons: I had started practicing web design and development from a very early time, and I gained a unique background and knowledge with my work with Counter-Hack. So in March 2005, being home only a few weeks from Mexico and still with a heavy mexican accent, I was approached to work with a company called <a href="http://www.cevo.com/">CEVO</a>. It was an online video game league that was emerging, and their first game was Counter-Strike. They needed someone to help consult with preventing cheating and &#8220;hacking&#8221; in their matches, and I was a perfect fit. So I joined as a consultant, and quickly became the Operations Director within a few months. CEVO also had brought on <a href="http://www.linkedin.com/in/rivulent">Eric Ping</a> to be the CTO, and the company started to grow.</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-v3.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-v3-150x150.jpg" alt="CEVO Version 3" title="CEVO Version 3" width="150" height="150" class="alignright size-thumbnail wp-image-776" /></a>One of the challenges CEVO faced was it was a completely distributed team. Charlie Plitt, the owner, lived in Baltimore, MD, Eric lived in Ephrata, WS, and I lived in Ogden, UT. We had staff and volunteers that literally lived in all 50 states except Hawaii and Alaska, as well as some across Canada. Our customers also lived all over North America, and we relied on the Website, Email, and VoIP to run the entire company. It was insane and awesome at the same time. This put a ton of demand on Eric, our only developer for the website, to get new features implemented quickly. During the first two years, we had re-designed the website a total of 6 times before finally settling down on the current design, which is being redesigned now as well. Eric couldn&#8217;t handle it all, and since we didn&#8217;t have the funds to hire another developer, I thought since I knew something about web design and programming, I could help out.</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-v4.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-v4-150x150.jpg" alt="CEVO Version 4" title="CEVO Version 4" width="150" height="150" class="alignright size-thumbnail wp-image-777" /></a>Eric took me under his wing and basically mentored me along as I started to take on project after project. I had become familiar with PHP and MySQL when I was tinkering with Counter-Hack&#8217;s code, but now I was really learning. I was also learning extremely quickly because I had no other option. It wasn&#8217;t like working at another company where I had a team of Senior Developers that could bail me out. Eric worked such late hours that normally if I was awake, he was asleep, and we meet for a few hours in the afternoon and evenings. But if I had a bug, or a problem, there was only one person who could solve the problems: <strong>myself</strong>. Working on a team of two developers for a start-up company is extremely demanding, and I was constantly looking for ways to work more efficiently. It was the only way to meet CEVO&#8217;s growing demands, by learning how to be a quicker and better developer. So while I had a day-job of doing Tech Support for a local company, I spent every other free moment working for CEVO. As CEVO grew, we ran into scaling problems and performance problems, things a normal &#8220;Jr. Developer&#8221; wouldn&#8217;t have hands-on experience dealing with. </p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-current.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/cevo-current-150x150.jpg" alt="CEVO Current Version" title="CEVO Current Version" width="150" height="150" class="alignright size-thumbnail wp-image-778" /></a>Eventually, I had learned so much working for CEVO, that I was able to quit my day-job doing tech support, and did contract work on the side. I helped launch some e-commerce websites, some basic business websites, and spent the rest of the time working on CEVO. I had started to go back to school for my Business Administration degree at WSU, and I was pretty much busy non-stop. But it was a lot of fun, and allowed me a lot of freedom not having a normal 9 to 5 job.</p>
<h3>Ambient Partners, LLC</h3>
<p>In 2006, I had the most amazing thing happen to me: I met my wife. We had dated for almost a year and we decided to get married. So by the end of 2006, I had a serious realization: I needed a steady income. While contract work paid really well, I could go a month or two without a check from clients. When living at home with relatively no expenses with the exception of my car, I could get away with this. But health insurance, rent, groceries, etc. I couldn&#8217;t live that way. So I decided to find a full-time programming job. Fortunately, the company I had worked tech support at had split with their California office and changed names. They were a company primarily doing software for DVD Rental Kiosks, and needed a Web Developer to do work on their web technologies. So by January 1st, 2007, I became a full-time employee for Ambient Partners. Our development team consisted of myself, a Senior Developer, and the CTO. As I look back at what the three of us accomplished as a development team, it amazes me. </p>
<p>When I joined, our main client had about 100 kiosks in the field. After doing the company website, I was given a very big project: RBO, Rent-Buy-Online. We wanted to provide clients with &#8220;white-label&#8221; solution to allow people to reserve and buy DVDs on a website, and then go pick them up at a Kiosk. There were two parts to this solution. The website itself, and the web services to supply the website with data. I had never written web services before, so I had a lot to learn very quickly. Also, it was to be written completely in ASP .NET, a framework, and C#, a language, I had never worked with before. So I started to learn how to build this project in .NET. It was very difficult on multiple fronts, but on in particular that I had underestimated was going from a loosely-typed language (PHP) to a strongly-typed language (C# .NET). So I tried several different methods, started a few different projects, and after a three months I got an email from my boss. It was short and sweet: &#8220;Justin, money is tight and we can&#8217;t afford to keep you on staff if you&#8217;re unable to make real progress on RBO. Either we need to see some real progress very soon, or staffing changes will be made.&#8221;</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/blockbuster-express.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/blockbuster-express-150x150.png" alt="" title="blockbuster-express" width="150" height="150" class="alignright size-thumbnail wp-image-771" /></a>I learned very quickly that spinning your wheels trying to do something perfect, but never getting done, is an excellent way to stay unemployeed. I immediately shifted gears after the thought of explaining to my new wife that I had lost my job. Fortunately, after the fear of doing something wrong was overcome by my fear of not finishing anything, I completed RBO to version 1 in record time. I had made some ugly coding decision that we refractored out later, or scratched completely, but it was a working prototype. My boss was happy, and I was happy and still employed. While the front website has been redone for <a href="http://www.blockbusterexpress.com/">Blockbuster Express</a>, it is powered by the same web services I built in 2007. </p>
<p>After building RBO, I was tasked with building a reporting &#038; support suite that would manage millions of transactions. This second project went much smoother, and I put a lot of effort into it. I knew the people making the decision whether or not to buy our multi-million dollar software suite would be personally using this piece of our solution, so I wanted it to make them really smile. I was told after the demo of our new software suite, the executives all mentioned they were looking forward to using their &#8220;executive reporting tool.&#8221; Several months later, after successfully building some pretty slick software with the rest of the team (of which other things were even cooler then what I made, like Chris&#8217;s auto-updater system), Ambient Partners was purchased by <a href="http://www.ncr.com/">NRC</a>.</p>
<h3>Dating DNA</h3>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/ddna-0.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/ddna-0-150x150.jpg" alt="Dating DNA" title="Dating DNA" width="150" height="150" class="alignright size-thumbnail wp-image-787" /></a>By 2008 when the NCR deal was underway, I had a choice. I could stay, take a very nice raise, and work for a very large corporation. But, deep down inside, I had a bad feeling about working for NCR. As a small team, we were very effective and there was almost zero political or bureaucratic non-sense in Ambient. As for NCR, I would go from being a developer in a company of three developers to a company of hundreds, if not thousands, of developers. I was also tired of working in .NET and Web Services, as I was moving away from what I loved to do: building cool websites with cool technology. </p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/datingdna-1.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/datingdna-1-150x150.jpg" alt="" title="datingdna-1" width="150" height="150" class="alignright size-thumbnail wp-image-788" /></a>My father at the same time was working on his new business: <a href="http://www.datingdna.com/">Dating DNA</a>. They had a web developer in San Diego, but he was expensive because living in San Diego is expensive. So Kevin asked me if I would be interested in working for Dating DNA. We tested the waters by having myself build a Web-based iPhone App for Dating DNA (the App SDK hadn&#8217;t been released yet.) It worked really well, so I turned down the offer to become an NCR employee, and returned to my roots as a developer: working from home working with code I love.</p>
<p>Through 2008 and 2009 I worked as a full-time developer for Dating DNA. I took over all responsibilities for all their technology. <a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/ddna-iphone.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/ddna-iphone-150x150.jpg" alt="" title="ddna-iphone" width="150" height="150" class="alignright size-thumbnail wp-image-789" /></a>In those two years, we did a lot. I&#8217;ll have to write a new blog post to completely cover everything we did that was awesome, but here were a few highlights: Built a real-time score generation system that could calculate hundreds of scores per second. Built the iPhone&#8217;s first Dating App, and to this day is a top ranking App in the charts and highest rated dating app. We scaled from 3,000 users to hundreds of thousands of users. We built a handful of new iPhone Apps, the main one being Clipish. We built custom chat rooms using Ajax and Comet, and a bunch of other stuff.</p>
<h3>Alienware &#038; CEVO</h3>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/alienware-arena.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/alienware-arena-150x150.png" alt="" title="alienware arena" width="150" height="150" class="alignright size-thumbnail wp-image-772" /></a>All this time, I was still doing work in the evenings with CEVO. In 2009, we were approached with the opportunity to do something we hadn&#8217;t done before in CEVO. Dell&#8217;s brand <a href="http://www.alienware.com/">Alienware</a> wanted us to make them a website like CEVO&#8217;s, only completely branded for Alienware. We built, from the ground up, and custom solution for Dell and Alienware, and <a href="http://www.alienwarearena.com/">Alienware Arena</a> was born. This was a great project to work on, and we were able to get it done on an extremely tight timeline and a strict budget. I did 100% of all the graphical design, following Alienware&#8217;s look and feel, and I&#8217;m very proud with the result. It was built by myself, Eric Ping, and our new talented developer Mike Stevens. While I can&#8217;t say how many members Alienware Arena now has, it is <strong>a lot</strong>. Building such a successful website for a large company like Dell doesn&#8217;t come around very often. Each year Dell has us add more and more features to it, and it has been a great project for CEVO.</p>
<h3>Utah Open Source</h3>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/utosc.jpg"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/02/utosc-150x150.jpg" alt="" title="utosc" width="150" height="150" class="alignright size-thumbnail wp-image-792" /></a>One thing that happened in November 2008 that I would consider one of the crucial events that &#8220;fast-tracked&#8221; my education as a web developer was being introduced to the local Open Source groups in Utah. I <a href="http://www.justincarmony.com/blog/2008/11/13/speaking-utah-php-usergroup-streamlined-web-development/">spoke</a> at the <a href="http://uphpu.org">Utah PHP Usergroup</a> and was introduced to the <a href="http://utos.org">Utah Open Source Foundation</a>. Through these groups, I met dozens, and eventually hundreds, of  talented, passionate people. While through CEVO I fast-tracked my web design and PHP development, through the Open Source groups I broadened my knowledge of so many more technologies. I learned about <a href="http://nginx.org/">nginx</a>, <a href="http://www.nagios.org/">nagios</a>, <a href="http://redis.io/">redis</a>, <a href="http://memcached.org/">memcached</a>, <a href="http://php.net/manual/en/book.apc.php">php apc</a>, linux server administration, and <a href="http://git-scm.com/">Git</a> just to name <em>a few</em> off the top of my head. What is great is not only did I learn about these things, but I met people who know a lot about them. So when I ran into problems, I already knew a solution that could work, <strong>and</strong> knew people I could ask questions too. That, and I&#8217;ve made a lot of great friends through the different meetings, lunches, and <a href="http://www.flickr.com/search/?q=%23utosc&#038;s=rec#page=0">conferences</a>. I&#8217;ve picked up some contract work through my connections with these groups, and overall they have been extremely beneficial and great.</p>
<h3>Chief Technology Officer</h3>
<p>All of these different things played a part in me having the job I have today, CTO of Dating DNA. <a href="http://www.justincarmony.com/blog/2010/10/19/new-job-cto-of-dating-dna/">I&#8217;ve written already</a> about my new responsibilities as our new CTO, and what it means for the company. These few short months as CTO we&#8217;ve made a lot of changes to handle even more scaling (especially with holiday surges and such). We&#8217;re in the process of improving our already fast score generation system, and moving our user photos to a more scalable solution in the near future. We&#8217;re evaluating our usability and such for our website, and seeing if a redesign on certain areas would be beneficial. There is a lot of work to be done, but I truly enjoy it.</p>
<h3>Advice &#038; Lessons Learned</h3>
<p>After reading and thinking about the different things I&#8217;ve experienced and gone through to get me to this point, I&#8217;ve had a few thoughts that I think can help anyone in our field, and other fields of work:</p>
<ul>
<li><strong>Surround yourself by people who help each other learn</strong> &#8211; Looking back, all of the people who have really helped me along with my career and education (not just schooling) have been people who help everyone learn. They each others things, and then learn from others. They harbor a culture of continual learning, and being in the tech industry which is always changing, this is critical.</li>
<li><strong>Always be learning something new, always</strong> &#8211; Trust me, there is always something to learn in this industry. Even if you&#8217;re learning something that isn&#8217;t directly involved, you never know what it might lead to. My work with Counter-Hack lead me to CEVO, which in turn lead to an accelerated web development &#8220;course&#8221; of &#8220;holy crap, we need to get this done and working or we crash and burn.&#8221; Even to this day, a lot of the things I learned about how hacks work I apply in other areas of computer science.</li>
<li><strong>Don&#8217;t let formal education be your <em>only</em> source of knowledge</strong> &#8211; Those that know me know I can be a little &#8220;harsh&#8221; when talking about formal educational institutions. Especially my frustrations with certain types of developers that are produced from these institutions. But the bottom line is this: they can be a great source of knowledge, and you can learn a lot from them. However, if you don&#8217;t learn additional information outside of the classroom, you are going to be sorely disappointed at how much you know when you graduate. Fundamentals are crucial, but practical application is just as important.</li>
<li><strong>Apply and build something important to you</strong> &#8211; There isn&#8217;t a better teacher than experience, and getting is as soon as possible, and as frequent as possible, will help a lot. I&#8217;ve spent more years unprofessional doing my job than professionally (at least for another year or two). Working on something meaningful to you, not just going through the motions of tutorials, really teach someone what it is like to do this kind of work.</li>
<li><strong>Networking and getting to know people is crucial</strong> &#8211; There is such an important emphasis on skill in the technical world, that knowing people and their actual abilities is vital. Also being know for your set of knowledge is important. That way when you want to learn something new, you know who to seek out. Before becoming Dating DNA&#8217;s CTO, and the rumor went out I was considering a new job, I had <strong>a lot</strong> of people contact me to see if I was interested in certain positions. There is no down side to being a &#8220;social&#8221; developer. Just because this isn&#8217;t &#8220;Marketing&#8221; doesn&#8217;t mean social networking isn&#8217;t important. I personally don&#8217;t like the term &#8220;networking&#8221; since it makes it seem like a chore. Make lots of friends in the programming groups and circles in your area and community, and it will be beneficial.</li>
<li><strong>Love what you do</strong> &#8211; If you don&#8217;t love what you do, then there is a good chance you will not go far in this industry. It doesn&#8217;t mean this is the <em>only</em> thing you do. Other hobbies and activities are important. But if you dread going to work, and do your work, every day, then it&#8217;s time to find something else.</li>
</ul>
<p>This went a lot later in the evening than I thought, so I hope my thoughts are coherent, and if nothing else, entertaining. Its been a great deal of fun since those first days with Photoshop 3 trying to design something that didn&#8217;t look terrible. I look forward to the next few decades to see where web technology takes us.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/09/14/so-you-want-to-be-a-web-developer/' rel='bookmark' title='So You Want To Be A Web Developer?'>So You Want To Be A Web Developer?</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/15/web-development-10-years-ago-now/' rel='bookmark' title='Web Development 10-Years Ago &amp; Now'>Web Development 10-Years Ago &#038; Now</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/15/being-a-productive-developer/' rel='bookmark' title='Being a Productive Developer'>Being a Productive Developer</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/02/23/how-i-became-a-web-developer-cto/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Sleeping Connections &amp; PHP</title>
		<link>http://www.justincarmony.com/blog/2011/01/08/mysql-sleeping-connections-php/</link>
		<comments>http://www.justincarmony.com/blog/2011/01/08/mysql-sleeping-connections-php/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 20:51:48 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[jet profiler]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[optimizations]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=706</guid>
		<description><![CDATA[If you want to skip to the explanation, just read below. But before then, here is a little background. A Little Background On January 2nd, we started to run into some serious performance problems with Dating DNA, so we began the process of going and deciding what were our problems, and how to optimize them. ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/03/mysql-does-table-exist-wo-throwing-errors/' rel='bookmark' title='MySQL &#8211; Does Table Exist w/o Throwing Errors'>MySQL &#8211; Does Table Exist w/o Throwing Errors</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/mysql_logo.gif"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/mysql_logo.gif" alt="" title="mysql_logo" width="300" height="167" class="alignright size-full wp-image-710" /></a><strong>If you want to skip to the explanation, just read below. But before then, here is a little background.</strong></p>
<h2>A Little Background</h2>
<p>On January 2nd, we started to run into some serious performance problems with <a href="http://www.datingdna.com/">Dating DNA</a>, so we began the process of going and deciding what were our problems, and how to optimize them. At the beginning, the Database was the bottleneck. It would get flooded with requests, and unable to handle them all, each query would slow down. We were using a tool called <a href="http://www.jetprofiler.com/">Jet Profiler</a> (which I will post about more in detail later), but here is a graph it would output before we started out optimizations:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-JP-Jan1.gif"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-JP-Jan1.gif" alt="" title="DDNA-JP-Jan1" width="600" height="214" class="alignnone size-medium wp-image-707" /></a></p>
<p>The light blue is total threads connected. The dark blue is thread running a query. The red are threads that are taking 2 seconds or longer to run, which are slow queries. The red is bad, very bad. So we were getting in bad shape. It was lovingly nick named &#8220;The Red Zone&#8221; while we were working on optimizations. Now, granted, we weren&#8217;t in &#8220;The Red Zone&#8221; the whole time, but when things got busy, things would slow down.</p>
<p>But optimization after optimization, we started to get things more and more under control:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-JP-Chat2.gif"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-JP-Chat2.gif" alt="" title="DDNA-JP-Chat2" width="600" height="154" class="alignnone wp-image-714" /></a></p>
<p>After about three days of optimizations, we get back down to a manageable load:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-JP-PostOps.gif"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-JP-PostOps.gif" alt="" title="DDNA-JP-PostOps" width="364" height="331" class="alignnone size-full wp-image-716" /></a></p>
<h2>The Problem</h2>
<p>However, when the website was having high traffic, we noticed an anomaly, which looked like &#8220;blue waves.&#8221; We lovingly gave them the nickname of &#8220;<a href="http://www.youtube.com/watch?v=2AwvRzOh4RA">blue meanies</a>&#8221; from the Beatles&#8217; <a href="http://en.wikipedia.org/wiki/Yellow_Submarine_%28film%29">Yellow Submarine Cartoon</a>. On Jet Profiler, here is what it would report:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-BlueWaves.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-BlueWaves.png" alt="" title="DDNA-BlueWaves" width="600" height="184" class="alignnone wp-image-717" /></a></p>
<p>It would get worse and worse, these big blue waves of connections reporting as &#8220;sleeping.&#8221; At first we didn&#8217;t think it would be a problem. However, when ever we had &#8220;blue meanies&#8221; the site and iPhone app felt really slow. So, I won&#8217;t cover all the things I tested and tried that didn&#8217;t work, but he is ultimately how we figured out our problem.</p>
<h2>The Solution</h2>
<p>At first, I thought it was an issue with Garbage Collection with PHP. So I set the wait_timeout on MySQL to something really low, like 5 seconds. We then started to get errors all over the website, so we knew that they were legitimate connections from PHP. The only thing that made sense is that PHP &#038; Apache now had become the bottle neck, that MySQL was returning requests so quickly that the threads were almost always sleeping, waiting for the PHP to finish. We slowly started to disable different functions on the website, trying to narrow down if there was a particular part of the website that was causing it. After a few hours, we figured out the feature: the ChatWalls. So we started to investigate why turning off the ChatWalls would make MySQL run faster, since we had moved the ChatWalls completely off MySQL and to run on Redis.</p>
<p>What we found is one particular function had a typo, that would cause PHP to iterate over an array not 10 to 20 times, but 1,000-2,000 times or more. This function was also called <strong>a lot</strong> by several Ajax calls. So, I fixed the typo, and the blue waves went away. </p>
<p>What was happening is Apache &#038; PHP were spending so much time processing the buggy function, that it would cause the rest of the web requests to slow down greatly. That would keep open may too many MySQL connections, causing the blue ways, and slowing down the website even more.</p>
<p>So in reality, the blue waves were a symptom of the problem, not the cause. It is the whole <a href="http://en.wikipedia.org/wiki/Correlation_does_not_imply_causation">Correlation vs Causation</a> situation (which I probably should blog about in more detail when it comes to finding performance issues). </p>
<p>So if you have a lot of sleeping connections, but MySQL is performing well, most likely it is PHP or Apache slowing things down. I hope this can help those having a similar problem. As for our Database, its working well now. A few more problems to iron out, but it is running really fast. The few red spikes are from the score generation system that are doing bulk inserts, and do not slow down the end user experience:</p>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-FP-Today.gif"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/DDNA-FP-Today.gif" alt="" title="DDNA-FP-Today" width="600" height="274" class="alignnone wp-image-720" /></a></p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/03/mysql-does-table-exist-wo-throwing-errors/' rel='bookmark' title='MySQL &#8211; Does Table Exist w/o Throwing Errors'>MySQL &#8211; Does Table Exist w/o Throwing Errors</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/01/08/mysql-sleeping-connections-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Chatroom / Walls with Redis &amp; PHP</title>
		<link>http://www.justincarmony.com/blog/2011/01/07/creating-chatroom-walls-with-redis-and-php/</link>
		<comments>http://www.justincarmony.com/blog/2011/01/07/creating-chatroom-walls-with-redis-and-php/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 00:15:16 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=700</guid>
		<description><![CDATA[Preface: This is not a step-by-step tutorial, but more of an outline on what I did. Also, I wrote this really quickly before heading off to dinner, so if there are parts that are unclear, or you have questions about, please leave a comment! This last week has been a roller coaster for us at ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2010/10/15/large-mysql-conversion-innodb/' rel='bookmark' title='Large MySQL Conversion &amp; InnoDB'>Large MySQL Conversion &#038; InnoDB</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/05/20/memcached-simple-effective-and-powerful/' rel='bookmark' title='Memcached: Simple, Effective, and Powerful'>Memcached: Simple, Effective, and Powerful</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/shot_1290206640.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/shot_1290206640.png" alt="" title="shot_1290206640" width="318" height="165" class="alignright size-full wp-image-701" /></a><em>Preface: This is not a step-by-step tutorial, but more of an outline on what I did. Also, I wrote this really quickly before heading off to dinner, so if there are parts that are unclear, or you have questions about, please leave a comment!</em></p>
<p>This last week has been a roller coaster for us at <a href="http://www.datingdna.com/">Dating DNA</a>. We had an excellent holiday season, but with mass volume of new sign ups our servers started to slow down. Severely. Something you never want to have happen. So over this last week I&#8217;ve worked about 80 hours (though I&#8217;m a salary employee, woohoo&#8230; <img src='http://c747925.r25.cf2.rackcdn.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) and implemented a lot of new performance boots, and I have about four or five blog posts worth of discoveries I need to write. So before I forget them, I&#8217;m going to write them.</p>
<p>The first change I&#8217;d like to talk about is moving our ChatWalls (kind of like a Chatroom and Forums/Walls mashed up together) from a MySQL backend to a Redis backend (<a href="http://redis.io/">http://redis.io/</a>). This initial change actually only took about 4-5 hours. Working out some additional kinks we found with our ChatWalls took another day or so, but the Migration to Redis was extremely smooth.</p>
<p>First, to give you an idea about our ChatWalls, here is a video of myself using them:</p>
<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/YFxdyPJ89YY?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/YFxdyPJ89YY?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<p>Redis, in a very simplified explanation, is like Memcache as a Key Value storage in memory. However, it is persistent (data not lost after restart), has more advanced data types (hashes, sorted sets), has built in virtual memory options (entire dataset doesn&#8217;t have to always be in memory), and you have a lot of cool operations beyond what memcache has (return sorted sets by score, purge out old records from a set, etc).</p>
<p>Now, I&#8217;ll walk through the basics of installing Redis, getting it up and running, reading and setting data in Redis, and migrating our old content.</p>
<h2>Install Redis</h2>
<p>Ok, compiling and installing Redis is a dream. It is very easy. On this server it is running Ubuntu 8.04 LTS. You go to the <a href="http://redis.io/">Redis Website</a> and click on downloads. Get the latest stable version, and download it to the server (I used wget). Untar it (tar -zxvf /path/to/file.tgz), and go into the source code&#8217;s directory. Now, Redis uses a noticeably less amount of memory when compiled for 32bit versus 64bit due to pointer sizes (<a href="http://redis.io/topics/faq">see FAQ</a>). So to compile on a 64bit linux machine, you need to install libc6-dev-i386, which on ubuntu was &#8220;aptitude install libc6-dev-i386&#8243;.</p>
<p>Then, it was a simple &#8220;make 32bit&#8221; and &#8220;make install&#8221; and it compiled and installed redis in /usr/local/bin for me. Now, I wanted it to start up for me automatically when I rebooted the server, so I saved <a href="http://www.ianlewis.org/en/redis-initd-script">this init.d script</a> as /etc/init.d/redis. Then I copied the sample configuration file out of the source file to /etc/redis/redis.conf. I ran &#8220;sysv-rc-conf&#8221; to set the Runlevels for it to execute the script at (2, 3, 4, and 5). If you don&#8217;t see &#8220;redis&#8221; listed, make sure you chmod +x /etc/init.d/redis so that it is executable. </p>
<p>Then I ran the command &#8220;/etc/init.d/redis start&#8221; and it was running. </p>
<h2>Redis &#038; PHP &#8211; Rediska</h2>
<p>Now, while looking for a PHP Redis library I found <a href="http://rediska.geometria-lab.net/">Rediska</a>. The documentation was pretty basic and straight forward, and I was able to get it installed pretty easy into my PHP App. Now, this library isn&#8217;t perfect, I found a few bugs while implementing it, especially with some values legal values for <a href="http://redis.io/commands/zrangebyscore">ZRANGEBYSCORE</a> as defined by the Redis documentation, but Rediska would throw exceptions because I was passing non-int values. I&#8217;ll submit some bugs with patches to them next week so they can update Rediska.</p>
<p>A few things to look over in the Rediska library: first off, read how they <a href="http://rediska.geometria-lab.ru/documentation/usage/instance-manager/">manage multiple instances of their Rediska class</a>. Its a little odd, but it works. I just don&#8217;t like passing an array with options in every command I have to make. So I would try something like $rediska->getHash(&#8216;key_value&#8217;); and expect it to return a Rediska_Key_Hash object, but it would just return an array. So, in the end, I ended up using very little of the other Rediska classes, and stuck to just using the Rediska class and it&#8217;s methods. The good thing is they have good phpDocs, so if you have a good IDE, it will be easy to know which method does what.</p>
<h2>Designing for a Key-Value Database Store</h2>
<p>Now, I highly recommend reading this article on the <a href="http://redis.io/topics/data-types-intro">different Redis Data Types</a>. Also, give a look over their <a href="http://redis.io/topics/twitter-clone">PHP Twitter Close with Redis</a>, since they show some of the techniques for using a Key-Value as a data store.</p>
<p>So the very, very first thing you must do, and we did, is map out how you will design your application for Redis. You don&#8217;t have tables and columns any more, just a really big array with some cool tricks. So unlike MySQL if you have a typo in your table or field name, you won&#8217;t get errors. It will just run, but you application will have some serious bugs. So pick a naming convention, and document exactly the &#8220;tables&#8221; and &#8220;keys&#8221; you&#8217;ll be using, with what data types, and stick to it. If you don&#8217;t, you will be hating life. &gt;/soap_box&lt;</p>
<p>I like the following naming convention. Separate word groups by periods (.) and preface changing variables (like an ID) with a colon (:). So, here some map definitions for our keys:</p>
<blockquote><p>
<strong>chatwall.viewers > Hash[user_id] viewer_json</strong> &#8211; A hashtable with a key of the user id and a value of the member&#8217;s json object. This will hold the entire list of all users.</p>
<p><strong>chatwall.wall:{wall_id}.viewers > Hash[user_id] viewer_json</strong> &#8211; A Hashtable that will hold a list of all the viewers for a given room. Example key: chatwall.wall:382.viewers</p>
<p><strong>chatwall.nextPostId > Int</strong> &#8211; A int we will auto increment to get unique post IDs</p>
<p><strong>chatwall.posts > Hash[post_id] post_json &#8211; The data for a post in a json object.</strong></p>
<p><strong>chatwall.wall:{wall_id}.posts > SortedSet</strong> We will store the score AND member as the Post ID. This will allow us to quickly get the last 50 posts in a set, and even pass a minimum Post ID to only get new ones.</p>
<p>[...]</p>
<p><strong>cache.chatwall:{wall_id}.information > Json String</strong> &#8211; This will hold a json string of the cached wall information from MySQL.
</p></blockquote>
<p>These were just some of the definitions. Now, these definitions are for documentation only. You can use whatever naming conventions on the fly and Redis will use it. But it will be extremely useful if you have a list of what the key names are. </p>
<p>We also prefaced any &#8220;cached&#8221; data, so data that we treat like it was in memcached, with the string &#8220;cache.&#8221; The reason being if we wanted to clear any cached data, we easily could do so with a custom script. But we don&#8217;t want to confuse any of our good data we want to stay persistent being deleted on accident.</p>
<h2>Refactoring the Code</h2>
<p>Now, one thing that I was extremely grateful for when I designed the ChatWall system is each type of data had a PHP class with members, and functions that would perform the CRUD operations. So it was extremely easy to change the CRUD functions to read/write to Redis, and instead of writing out a query, I generated a key and passed for the value the variable $this. Super easy. Having all the data access code encapsulated correctly made it easy to simply go down my class methods and re-write them.</p>
<p>Now, there were a few caveats. One was moving posts, because an admin could move a post to a different forum or chatroom. Because we depended on Indexes from MySQL to catch the move, on our update commands we had to check the old record first to see if the room moved. If it did, we would have to remove an entry from the old chatwall.wall:{id}.posts and put it in the new one.</p>
<h2>Migrating the Data</h2>
<p>I simply wrote a script to select the data from our MySQL tables, set them to the new Classes, and called the &#8220;InsertRecord&#8221; function. In 10 seconds the script had migrated all of our data to Redis, which was taking up 25M of data in Redis. Pretty awesome.</p>
<h2>Performance</h2>
<p>I couldn&#8217;t be happier. It is really, really fast now. We had to double check our php code to prevent any calls to the Database, and make sure Redis had all the information it needed. Once we fixed a few areas, and our ChatWalls calls were being all 100% being executed against Redis, it was blazing fast. I am really, really happy with the change.</p>
<p>I would recommend getting and installing the <a href="https://github.com/antirez/redis-tools">redis-tools</a> for your server. They make it really easy to see what your Redis server is doing. Our server is currently serving up 200-500 requests per second, and using up about 2-5% of our CPU with 20-30MB of ram. The background saves take 2-3 seconds to perform.</p>
<p>Bottom line, I highly recommend checking out Redis. I wouldn&#8217;t recommend replacing MySQL with it, but using it along side MySQL to handle cached data and highly accessed/changed data. It has been a huge performance boost for Dating DNA. We are in the process of finishing migrating our Match Score System to Redis, which is quite a bigger project. 500 million rows big. But it is going great, and looking to finishing with that project soon.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2010/10/15/large-mysql-conversion-innodb/' rel='bookmark' title='Large MySQL Conversion &amp; InnoDB'>Large MySQL Conversion &#038; InnoDB</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/05/20/memcached-simple-effective-and-powerful/' rel='bookmark' title='Memcached: Simple, Effective, and Powerful'>Memcached: Simple, Effective, and Powerful</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/01/07/creating-chatroom-walls-with-redis-and-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Large MySQL Conversion &amp; InnoDB</title>
		<link>http://www.justincarmony.com/blog/2010/10/15/large-mysql-conversion-innodb/</link>
		<comments>http://www.justincarmony.com/blog/2010/10/15/large-mysql-conversion-innodb/#comments</comments>
		<pubDate>Sat, 16 Oct 2010 03:01:32 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[conversion]]></category>
		<category><![CDATA[DataSet]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[scaling]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=658</guid>
		<description><![CDATA[Over the last week at Dating DNA, we&#8217;ve re-engineered our internal mail system that users use to send messages to each other. It took a few days longer to convert and re-engineer everything, but we finally made the change. With the exception of two small bugs, it all went off without a hitch. But before ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/03/mysql-does-table-exist-wo-throwing-errors/' rel='bookmark' title='MySQL &#8211; Does Table Exist w/o Throwing Errors'>MySQL &#8211; Does Table Exist w/o Throwing Errors</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/06/digital-conversion-video/' rel='bookmark' title='Digital Conversion Video'>Digital Conversion Video</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2010/10/logo_mysql.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2010/10/logo_mysql-150x150.png" alt="" title="logo_mysql" width="150" height="150" class="alignright size-thumbnail wp-image-666" /></a>Over the last week at <a href="http://www.datingdna.com/">Dating DNA</a>, we&#8217;ve re-engineered our internal mail  system that users use to send messages to each other. It took a few days longer to convert and re-engineer everything, but we finally made the change. With the exception of two small bugs, it all went off without a hitch. But before all the different things I learned doing it fade, I wanted to document them here.</p>
<p>First off, converting from one large set of InnoDB tables to a new structure. I&#8217;ve done <a href="http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/">something similar in the past</a>, and I think I&#8217;ve honed in a little bit more the technique. So here are some thoughts regarding doing this process.</p>
<ul>
<li><strong>Run Conversion on Separate Server</strong> &#8211; Looking back, I wish I had just spun up a beefy server at Rackspace Cloud, transferred the data, and gone to town running my conversion scripts. There were a few times where I tanked our Database server to the point of noticing slower load times on our website.</li>
<li><strong>Write to SQL Script Instead Directly</strong> &#8211; At first when I wrote my conversion scripts, it would read a dataset for a user, and the do inserts for each row into the Database to the new tables. If you&#8217;re doing less than 200,000 rows, this probably is fine. But doing 5 million or so takes too long.</li>
<li><strong>Insert Data By Primary Key Order</strong> &#8211; You&#8217;d think I would have learned my lesson from the last time I did this, but I found out even for a smaller data set of a few million (instead of tens of millions before). Inserting by the correct order saves a ton of time. The easiest way to think of it is if you had to put files into a filing cabinet. It would be much faster to just move them in pre-sorted, instead of sorting them as you add them. Also, InnoDB doesn&#8217;t know whether you are inserting 10 rows, or 10 million. So when you insert unsorted, it will spend a lot of resources shuffling around pages.</li>
<li><strong>Write Your Conversions Tools to be Robust</strong> &#8211; What you don&#8217;t want is for your script to only be able to run start to finish, and if it breaks, you have to start all over. What you want is to be able to run sections, test, rerun sections, convert large all sections, then right before you change to the new script, run the conversion of the newer entries.</li>
<li><strong>Monitor Status, Progress, &#038; Time Left</strong> &#8211; One thing you&#8217;ll definitely want to know is how long your script will take to run. You will get to be like Windows and try to guess how long something will take (and hopefully be more accurate). I like to keep it simple. I&#8217;m converting X1 million rows, I started a Y1 time, and now I&#8217;ve completed X2 conversions, and the current Time is Y2. So I figure out how long its taken me to do the ones I&#8217;ve finished, and calculate how long it will take to do the rest at the same rate.</li>
</ul>
<p>Hopefully this will help out someone else who is making a large scale conversion from one table structure to another.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/03/mysql-does-table-exist-wo-throwing-errors/' rel='bookmark' title='MySQL &#8211; Does Table Exist w/o Throwing Errors'>MySQL &#8211; Does Table Exist w/o Throwing Errors</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/06/digital-conversion-video/' rel='bookmark' title='Digital Conversion Video'>Digital Conversion Video</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2010/10/15/large-mysql-conversion-innodb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP HipHop – What It Means</title>
		<link>http://www.justincarmony.com/blog/2010/02/03/php-hiphop-what-it-means/</link>
		<comments>http://www.justincarmony.com/blog/2010/02/03/php-hiphop-what-it-means/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 16:32:04 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[hiphop]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=527</guid>
		<description><![CDATA[There has been a lot of speculation about PHP, Facebook, and a big announcement. Over the last few weeks, several predominate PHP community members were invited to the Facebook offices to check something out. Facebook asked the PHP members, as Ben Ramsey put it, to &#8220;make a gentleman&#8217;s agreement that I wouldn&#8217;t talk until FB ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/01/11/characteristics-of-good-php-code/' rel='bookmark' title='Characteristics of Good PHP Code'>Characteristics of Good PHP Code</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/14/so-you-want-to-be-a-web-developer/' rel='bookmark' title='So You Want To Be A Web Developer?'>So You Want To Be A Web Developer?</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/15/web-development-10-years-ago-now/' rel='bookmark' title='Web Development 10-Years Ago &amp; Now'>Web Development 10-Years Ago &#038; Now</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2010/02/HipHop_logo_white.png" alt="HipHop_logo_white" title="HipHop_logo_white" width="106" height="139" class="alignright size-full wp-image-526" /> There has been a lot of <a href="http://www.readwriteweb.com/archives/facebook_gets_faster_debuts_homegrown_php_compiler.php" target="_blank">speculation</a> about PHP, Facebook, and a big announcement. Over the last few weeks, several predominate PHP community members were invited to the Facebook offices to check something out. Facebook asked the PHP members, as Ben Ramsey put it, to &#8220;make a gentleman&#8217;s agreement that I wouldn&#8217;t talk until FB is ready.&#8221; </p>
<p>Well, Facebook has made their <a href="http://developers.facebook.com/news.php?blog=1&#038;story=358" target="_blank">announcement</a>, and it is called HipHop.  Here is an excerpt:</p>
<blockquote><p>Today I&#8217;m excited to share the project a small team of amazing people and I have been working on for the past two years; HipHop for PHP. With HipHop we&#8217;ve reduced the CPU usage on our Web servers on average by about fifty percent, depending on the page. Less CPU means fewer servers, which means less overhead. This project has had a tremendous impact on Facebook. We feel the Web at large can benefit from HipHop, so we are releasing it as open source this evening in hope that it brings a new focus toward scaling large complex websites with PHP. While HipHop has shown us incredible results, it&#8217;s certainly not complete and you should be comfortable with beta software before trying it out.</p>
<p>HipHop for PHP isn&#8217;t technically a compiler itself. Rather it is a source code transformer. HipHop programmatically transforms your PHP source code into highly optimized C++ and then uses g++ to compile it. HipHop executes the source code in a semantically equivalent manner and sacrifices some rarely used features — such as eval() — in exchange for improved performance. HipHop includes a code transformer, a reimplementation of PHP&#8217;s runtime system, and a rewrite of many common PHP Extensions to take advantage of these performance optimizations.</p></blockquote>
<p>Marco Tabini has a nice <a href="http://blog.tabini.ca/2010/02/hiphop-what-you-need-to-know/" target="_blank">summary</a> on what PHP need to know about HipHop. However, people I&#8217;ve talked to have had several opinions on HipHop, ranging from pure delight to doubts to indifference. Personally I think this is a great thing for PHP, and I&#8217;ll tell you why.</p>
<p><strong>HipHop will enabled business to pick a web scripting language and use it from start-up to internet-giant.</strong> While HipHop isn&#8217;t the first tool used to speed up PHP, such as APC, Memcached, and others; it is more of a current reminder: PHP is serious about the web. For people already using PHP, this is just a nice feature. For those who aren&#8217;t using PHP, it shows that it is a <strong><em>very</em></strong> strong candidate. </p>
<p>I&#8217;ve worked in a non LAMP shop before. To non-PHP people, it has the stigma, regardless of <em>actual</em> performance, of being hard to scale. It is a &#8220;scripted language&#8221;, and in the Java / .NET world where I was working, it was looked at as being an absurd choice. Now, PHP can make a strong case of being able to mature with your application and scale appropriately. </p>
<p>One fear that I have as a Project Manager, and anyone has who decided on the technology that they will implement, is &#8220;picking the wrong team.&#8221; During my .NET days, Microsoft&#8217;s team announced a new technology for .NET applications. It showed a lot of promise and simplified some things that were a pain in .NET. Our team adopted the new technology and ran with it. It wasn&#8217;t perfect, but we liked it. Less than a year later, Microsoft announced that it would be moving the project to a drastically different team, which basically meant &#8220;there wasn&#8217;t enough adoption, so we&#8217;re putting this project on the back burner.&#8221; The new team was basically to maintain the code forward, but not develop new features.</p>
<p>What happened is we invested on this new technology, and we saw the potential it would have in the future. We lost our investment, since that future potential would never be realized. Now our projects had this new technology embedded in many spots. Re-writing those places would take a great deal of time. From a Project Manager perspective, it was a poor choice.</p>
<p>For PHP, the emergence of HipHop, a concept that is working across thousands of production servers, it sends a <strong>strong message</strong> to the web development community as a whole. <strong>Not only is PHP widely adopted, flexible yet powerful, and easy to implement. PHP is competitive, and is continually evolving to adapt to web developer&#8217;s needs.</strong> It is a safe bet for many projects, and it isn&#8217;t going anywhere but up.</p>
<p>Will I be implementing HipHop right now? Probably not. Ilia Alshanetsky has a very healthy <a href="http://ilia.ws/archives/213-My-Thoughts-on-HipHop.html#extended" target="_blank">reality check</a> on what HipHop is for. But the bottom line is I don&#8217;t need what HipHop is offering <em>yet</em>. I can see very great uses in the future for Dating DNA&#8217;s compatibility generation, as well as certain pieces of other PHP projects that could use a serious performance boost. But for now, my Blog will not be HipHoping along. I&#8217;m excited for not only what HipHop does, but what it&#8217;s greater underlining meaning as a whole with PHP.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/01/11/characteristics-of-good-php-code/' rel='bookmark' title='Characteristics of Good PHP Code'>Characteristics of Good PHP Code</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/14/so-you-want-to-be-a-web-developer/' rel='bookmark' title='So You Want To Be A Web Developer?'>So You Want To Be A Web Developer?</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/15/web-development-10-years-ago-now/' rel='bookmark' title='Web Development 10-Years Ago &amp; Now'>Web Development 10-Years Ago &#038; Now</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2010/02/03/php-hiphop-what-it-means/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My 2009 Technology Recap</title>
		<link>http://www.justincarmony.com/blog/2009/12/23/my-2009-technology-recap/</link>
		<comments>http://www.justincarmony.com/blog/2009/12/23/my-2009-technology-recap/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 18:55:31 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[advice]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[Goals]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Presentation]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[UPHPU]]></category>
		<category><![CDATA[utah]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/2009/12/23/my-2009-technology-recap/</guid>
		<description><![CDATA[Its been two years now that I&#8217;ve been a more or less &#8220;serious blogger.&#8221; I had using the term blogger, since when people hear about blogs, they think of people either detailing their entire lives, or pumping some angel. For me, blogging has just been a way to share information with people I know locally, ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/09/16/speaking-utah-open-source-conference-2009/' rel='bookmark' title='Speaking: Utah Open Source Conference 2009'>Speaking: Utah Open Source Conference 2009</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/14/so-you-want-to-be-a-web-developer/' rel='bookmark' title='So You Want To Be A Web Developer?'>So You Want To Be A Web Developer?</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/' rel='bookmark' title='Presentation: Real Life Scaling'>Presentation: Real Life Scaling</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Its been two years now that I&#8217;ve been a more or less &#8220;serious blogger.&#8221; I had using the term blogger, since when people hear about blogs, they think of people either detailing their entire lives, or pumping some angel. For me, blogging has just been a way to share information with people I know locally, and those I don&#8217;t even know who find my blog via searching. I&#8217;ve had a few spurts where I blogged quite frequently, but for the most part it was just here and there.</p>
<p>I&#8217;ve gone back and looked at this year of 2009, and the things I&#8217;ve blogged about, and I thought I&#8217;d give a little recap.</p>
<p><b>My CSS Conversion</b></p>
<p>At the beginning of the year I realized I had <a href="http://www.justincarmony.com/blog/2009/01/08/css-im-100-converted/">100% percent to using CSS</a>. I&#8217;m still a little in awe that being such a table junkie I finally did it. There were a few key things that I did to help me learn all the difficult things with CSS. I hope I can help some poor web developer out there understand their CSS a little better.</p>
<p><b>A Year of PHP IDEs</b></p>
<p>I really invested some time in trying out and experimenting with <a href="http://www.justincarmony.com/blog/2009/02/06/aptana-studio-php-ide-alternative-to-pdt-zend-studio/">several PHP Integrated Development Environments (IDEs)</a>. I had been using Zend Studio for several years, however more and more I found myself frustrated with it&#8217;s quirks. However, I haven&#8217;t had time yet to blog about the new IDE I am using, <a href="http://netbeans.org/">NetBeans</a>. I&#8217;ve made the switch from Zend Studio to NetBeans, and while I&#8217;m not completely sold, I&#8217;m still giving it some time. Maybe over christmas break I&#8217;ll blog some about it.</p>
<p><b>Interesting Challenges w/ MySQL</b></p>
<p>While I haven&#8217;t blogged about most of them, I have had some interesting challenges w/ MySQL over the last year. One was converting <a href="http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/">40 Million rows from a MyISAM engine to an InnoDB Engine</a>. I&#8217;ve been having some serious heart-to-heart conversations with MySQL (metaphorically of course) on how I&#8217;m going to scale it to millions and billions of rows. I think I&#8217;ve mapped out in my head how we&#8217;re going to handle it for <a href="http://www.datingdna.com/">Dating DNA</a>. That will be one challenge I&#8217;ll be addressing in 2010.</p>
<p><b>New Blog Design</b></p>
<p>This year I got around to <a href="http://www.justincarmony.com/blog/2009/02/20/new-blog-design/">re-designing my blog using the Carrington Theme as a base</a>. I kinda like it, but it still could use a little more polish. One day I&#8217;ll find time to give it that extra polish.</p>
<p><b>Memcached</b></p>
<p>This year I really got into the theory on how to <a href="http://www.justincarmony.com/blog/2009/05/20/memcached-simple-effective-and-powerful/">design an application with Memcached</a>. I&#8217;ve decreased the load on several websites by using it, and wrote an <a href="http://www.justincarmony.com/blog/2009/06/24/writing-effictive-php-caches-with-memcached/">in-depth article on the theory of caching, and how to implement it effectively</a>. I&#8217;ve been amazed at how well it works, and that I hadn&#8217;t used it before.</p>
<p><b>A Year of Presentations</b></p>
<p>I&#8217;ve given two presentations this year, my <a href="http://www.justincarmony.com/blog/2009/06/24/writing-effictive-php-caches-with-memcached/">Memcached</a> presentation at UPHPU, and my &#8220;<a href="http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/">Real Life Scaling</a>&#8221; presentation at the Utah Open Source Conference. I got great feedback from both presentations, and I look forward to what I&#8217;ll present on this upcoming year. I&#8217;m thinking about putting together a presentation called &#8220;Being a Web Ninja with jQuery,&#8221; and showing of the dozen of awesome applications I&#8217;ve built using jQuery.</p>
<p><b>Utah Open Source Conference 2009</b></p>
<p>This year I helped organize and throw together the Utah Open Source Conference. I was made the Sponsorship Manager, and it was interesting trying to talk to companies in a recession about donating to a non-profit conference. I haven&#8217;t had a chance to blog about different techniques on how to professional ask for money for something like this, but hopefully in 2010 I&#8217;ll be able to share some insights.</p>
<h2>Things I Didn&#8217;t Blog About</h2>
<p>There were a lot of things I didn&#8217;t get around to blogging about this year. I&#8217;ll quickly touch on them here, and hopefully in 2010 I&#8217;ll be able to blog about them more.</p>
<p><strong>Web Services</strong> &#8211; I&#8217;ve done a LOT of web service work. Web services provide a unique challenge, since many times its hard to debug them. At my old job, one of the biggest challenges is we really couldn&#8217;t debug our web services until all of the other pieces of the puzzle were done. Then we spent long hours with trial and error, debugging via dumping logs. I&#8217;ve learned a lot of tricks with PHP and web services. Hopefully I&#8217;ll be blog more about those soon.</p>
<p><b>Performance Tuning LAMP</b> &#8211; I&#8217;ve had to do a lot of tuning to keep the Dating DNA website afloat. Because of the awesomeness of our iPhone apps, we&#8217;ve had a lot of load on our web servers. There are a lot of things you can do to get the LAMP stack to run well.</p>
<p><b>Alienware Arena</b> &#8211; Here was a fun little project I was able to crank out for probably the largest client I&#8217;ve done work for: Dell. We made them a website for their Alienware brand called &#8220;<a href="http://www.alienwarearena.com/">Alienware Arena</a>.&#8221;</p>
<p>
<a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2009/12/AlienwareArena.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2009/12/AlienwareArena-tm.jpg" width="400" height="352" alt="AlienwareArena.png" /></a></p>
<p>There were a lot of challenges to this website, mainly timeline and budget. But we were able to walk away happy with our work, and the Dell / Alienware team were really happy. It was interesting going through and trying to copy / mimic the look and feel of the Alienware website. I&#8217;m really proud of what we made.</p>
<p><b>Never Ending iPhone App Store Saga</b> &#8211; Anyone who knows me has heard of the bloody wars that my current employer has had with Apple, their iPhone, and the App Store. The ridiculous approval process, the extremely long wait periods, and Apple&#8217;s OCD when it comes to their phone. I won&#8217;t say much anything else on the topic, but boy it has been frustrating.</p>
<h2>What to Expect with 2010</h2>
<p>Boy, 2010 will be interesting. What to expect? I&#8217;ll be doing some pretty sick programming in jQuery, as I&#8217;ll be adding integrating chat to the Dating DNA website. What else? A <b><i>lot</i> <span style="font-weight: normal;">more when it comes to integrating websites into other social network platforms.</span></b></p>
<p><b><span style="font-weight: normal;">From a business platform, 2010 will be a lot of work spent on taking some great ideas and trying to monetize them. While working on awesome stuff is great, its important to pay the bills with them. I will have an entire year to sign up Sponsors for the 2010 UTOS Conference instead of 2 short months.</span></b></p>
<p>Hopefully I&#8217;ll get in a better habit of documenting my discoveries and solutions here in my blog. Sharing information is the best way to help everyone out.</p>
<p>I hope everyone has a happy holiday and good luck in the new year! 2010, here we come!</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/09/16/speaking-utah-open-source-conference-2009/' rel='bookmark' title='Speaking: Utah Open Source Conference 2009'>Speaking: Utah Open Source Conference 2009</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/14/so-you-want-to-be-a-web-developer/' rel='bookmark' title='So You Want To Be A Web Developer?'>So You Want To Be A Web Developer?</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/' rel='bookmark' title='Presentation: Real Life Scaling'>Presentation: Real Life Scaling</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2009/12/23/my-2009-technology-recap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Presentation: Real Life Scaling</title>
		<link>http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/</link>
		<comments>http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 18:39:44 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Presentation]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=500</guid>
		<description><![CDATA[Here are my slides for the presentation that I gave at the Utah Open Source Conference on Friday. It was an awesome conference, and I am glad that I was able to be involved. Real Life Scaling: A Tale of Two Websites View more presentations from Justin Carmony. If you have any questions or comments, ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/05/27/steamlined-web-development-presentation-video/' rel='bookmark' title='Steamlined Web Development Presentation Video'>Steamlined Web Development Presentation Video</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/12/06/100th-blog-entry-first-year-of-real-blogging/' rel='bookmark' title='100th Blog Entry &#8211; First Year of Real Blogging'>100th Blog Entry &#8211; First Year of Real Blogging</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/05/14/a-new-stage-in-life-my-macbook-pro/' rel='bookmark' title='A New Stage in Life: My MacBook Pro'>A New Stage in Life: My MacBook Pro</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Here are my slides for the presentation that I gave at the Utah Open Source Conference on Friday. It was an awesome conference, and I am glad that I was able to be involved.</p>
<div style="width:425px;text-align:left" id="__ss_2184608"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/JustinCarmony/real-life-scaling-a-tale-of-two-websites" title="Real Life Scaling: A Tale of Two Websites">Real Life Scaling: A Tale of Two Websites</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=reallifescaling-ataleoftwowebsites-small-091010143045-phpapp02&#038;stripped_title=real-life-scaling-a-tale-of-two-websites" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=reallifescaling-ataleoftwowebsites-small-091010143045-phpapp02&#038;stripped_title=real-life-scaling-a-tale-of-two-websites" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/JustinCarmony">Justin Carmony</a>.</div>
</div>
<p>If you have any questions or comments, please feel free to leave them below.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/05/27/steamlined-web-development-presentation-video/' rel='bookmark' title='Steamlined Web Development Presentation Video'>Steamlined Web Development Presentation Video</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/12/06/100th-blog-entry-first-year-of-real-blogging/' rel='bookmark' title='100th Blog Entry &#8211; First Year of Real Blogging'>100th Blog Entry &#8211; First Year of Real Blogging</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/05/14/a-new-stage-in-life-my-macbook-pro/' rel='bookmark' title='A New Stage in Life: My MacBook Pro'>A New Stage in Life: My MacBook Pro</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking: Utah Open Source Conference 2009</title>
		<link>http://www.justincarmony.com/blog/2009/09/16/speaking-utah-open-source-conference-2009/</link>
		<comments>http://www.justincarmony.com/blog/2009/09/16/speaking-utah-open-source-conference-2009/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 18:00:13 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Presentation]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[utah]]></category>
		<category><![CDATA[utos]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=455</guid>
		<description><![CDATA[I will be speaking this year at the Utah Open Source Conference this year. My presentation is &#8220;Real Life Scaling: A Tale of Two Websites.&#8221; Here is the abstract: Scaling is a real issue for many websites. However, many developers try to implement solutions used by the giants of the internet: Google, Facebook, Twitter, WordPress, ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/10/07/adeona-open-source-lojack-for-laptops/' rel='bookmark' title='Adeona &#8211; Open Source LoJack for Laptops'>Adeona &#8211; Open Source LoJack for Laptops</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/18/why-are-some-open-source-advocates-hypocrites/' rel='bookmark' title='Why Are Some Open Source Advocates Hypocrites?'>Why Are Some Open Source Advocates Hypocrites?</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/13/speaking-utah-php-usergroup-streamlined-web-development/' rel='bookmark' title='Speaking: Utah PHP Usergroup – Streamlined Web Development'>Speaking: Utah PHP Usergroup – Streamlined Web Development</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I will be speaking this year at the <a title="Utah Open Source Conference" href="http://www.utosc.com/" target="_blank">Utah Open Source Conference</a> this year. My presentation is &#8220;Real Life Scaling: A Tale of Two Websites.&#8221; Here is the abstract:</p>
<blockquote><p>Scaling is a real issue for many websites. However, many developers try to implement solutions used by the giants of the internet: Google, Facebook, Twitter, WordPress, etc. However, many of these techniques are designed for very unique and high demand situations. Implementing these techniques prematurely to smaller websites can lead to overly-complex solutions that can be difficult to manage, and even hinder progress.</p>
<p>See real life examples of from two popular websites: cevo.com and datingdna.com. Learn what challenges and bottlenecks they faced, and the solutions they created to overcome them. Find out what optimizations and implementations returned the greatest ROI for scaling with the project.</p>
<p>CEVO is an online gaming league that hosts thousands of matches for hundreds of video game events. They have contracted with DirectTV, Dell, and other companies to offer branded gaming events. Because the company is run by a staff spread across the USA and Canada, the website runs 100% of their business. Hundreds of gaming servers and player clients communicate with CEVO’s APIs to get real-time information. Learn how they’ve handled the ever increasing load on their servers.</p>
<p>Dating DNA is an online dating community that integrates with today’s popular social networking sites. The site has exploded since it released its iPhone App, which is currently the #1 iPhone Dating App. Learn how Dating DNA has scaled from having daily user sign-ups increase 1000% in a matter of weeks.</p>
<p>This presentation will be given by Justin Carmony, a lead developer for both projects.</p></blockquote>
<p>I will be speaking on Friday, Oct. 9th at 7:00 PM. I&#8217;m looking forward to presenting and have my slides done early for once. Hopefully you all will enjoy it! If you aren&#8217;t signed up to attend this year, really consider! It is going to be a very awesome, there are a lot of great of local, and national, presenters. Use the coupon <strong>UPHPU</strong> to get 50% off attendance! See you there!</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/10/07/adeona-open-source-lojack-for-laptops/' rel='bookmark' title='Adeona &#8211; Open Source LoJack for Laptops'>Adeona &#8211; Open Source LoJack for Laptops</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/18/why-are-some-open-source-advocates-hypocrites/' rel='bookmark' title='Why Are Some Open Source Advocates Hypocrites?'>Why Are Some Open Source Advocates Hypocrites?</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/11/13/speaking-utah-php-usergroup-streamlined-web-development/' rel='bookmark' title='Speaking: Utah PHP Usergroup – Streamlined Web Development'>Speaking: Utah PHP Usergroup – Streamlined Web Development</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2009/09/16/speaking-utah-open-source-conference-2009/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 38/131 queries in 0.049 seconds using memcached
Content Delivery Network via Rackspace Cloud Files: c747925.r25.cf2.rackcdn.com

Served from: www.justincarmony.com @ 2012-02-07 20:55:25 -->
