Ok, so i’ve been working away at my freelance position, but i’ve been helping someone scale their LAMP site.  Basically I was asked to provide guidance, or methodology on how to scale their LAMP application.  So here’s what I wrote in response:

(PS: If you’ve come across the site via Google, feel free to email me or post a comment with any questions you have.  I’ll be happy to answer them.)

I found this great primer for you:

Basically three things that slow down a site:
Bad SQL – make sure that all your sql is optimized and your indexes are set
Too many reads – your database is your bottleneck and its slowing everything down
Too many requests – your web server is your bottleneck and its slowing everything down

After you optimize your code, you want to cache things before you scale horizontally.  Scaling horizontally is adding more machines to your configuration.

Caching:
————
So the general rule is to cache as much as you can.  For the web servers IF you can cache it into HTML and just serve static pages that are updated when the user changes something, that would be best.

However if generating html pages doesn’t work, I usually run APC on all my servers.  APC precompiles your PHP code and stores it memory.  So there’s no need to parse the script again when the page is hit.  It also has a local caching mechanism that allows you to cache serialize variables and store them.   If your load balancer is set to sticky session (forcing the user to use the same web server) then it may be a good idea to store content that you called from the database into the APC cache.

Memcache is a much better solution for storing serialized info since it allows you to connect to a machine other than localhost.  So all your machines can dump data into memcache instead of one.  The benefit of this is that if one server updates values, then they can send it over to the main memcache table so everyone will have updated info.

What to memcache?  Generally I store anything that I pull from the database into memcache.  So lets say i have a user record, i’ll store it in memcache (you’ll have to play with expiration times based on how long your user sessions are).  When the user updates his record, i’ll go out and clear the memcache record for this user then reload it with the new record.  An easier way is to just clear the record, and let the next web server do the work of loading it up again.

For images and what not, you want to push all your images off your servers and into a content delivery network (CDN, such as s3+cloudfront or akamai).  This helps alleviate unnecessary load from your servers.  Think of it this way, your servers have to process image requests, find the files then open up connections to send the files to people.  Instead, if you move this burden to a CDN, your servers don’t have to do this anymore and can focus on just doing processing requests and php stuff.  Also, generally CDN’s are much cheaper when it comes to costs for bandwidth.

Scaling horizontally:
Ok, this is where EC2 comes in.  So lets say you’ve setup this awesome architecture that is caching stuff and your sql is awesome and optimized and quick, but your servers are still getting slammed by requests.  This is where you want to scale horizontally.

I’ll use ec2 as an example, because i just started playing with it myself.  The first thing you need to do for EC2 is figure out how you’re going to handle load balancing and dns.  Load balancing is generally the pain in the ass in EC2.  You’ll probably need one or two elastic ip’s for the load balancers, then just point the dns to one of the elastic ip’s.  There are several load balancing images that you can load for this.  If you have a load balancer off site already, then you can probably just add the public ips to your offsite load balancer.

Next setup your database.  You’ll want to get it setup on an s3 elastic block for storage.  there are a ton of write ups on this.  if you need help after that, email me.

After setting up your database, set up your web servers.  Again, ton of write ups on this.  If you need help email me.  Install the code, point it to the db.  Add the ip address that amazon assigns you to the load balancer.

What i recommend is doing this stuff manually for at least 2 – 3 months so you understand how everything works, BEFORE you use an automated tool like Scalr.  Its better if you understand what the implications of everything are before you automate it.

Ok, so everything is setup on EC2.  You have a db, you have dns, you have a load balancer, and you have web servers.  You’ll need monitoring software to track load.  I recommend Nagios, if you want to pay for it, there’s Keynote and Gomez to watch your site.  If you site starts to get slow, add another web server to the set.

Quick note:  if adding web servers is not working, then you probably have a database bottleneck.  This is a much bigger and messy issue.  You’ll have to setup master/slave or master/master replication to handle read/write scaling.  The write up I sent you (above) covers this in much greater detail. Essentially it comes down to this:  Writing is slower than reading.  So if you can offload your writes, to some other machine, it will speed things up.