Wordpress + W3 Total Cache + MaxCDN How-To

It's no secret that I'm a big fan of Wordpress as a blog and CMS platform. While it does have its problems, it's relatively simple to set up, it's extensible, and -- when properly configured -- it has great performance. The WP Super Cache plugin has been a staple on my Wordpress blogs for quite some time and it has solved almost all of my performance problems.

However, when you load up quite a few plugins or a heavy theme, the performance will dip due to the increased number of stylesheets, javascript files, and images. You can compress and combine the stylesheets and javascript to decrease load times, but this may not get the performance to a level you like.

I was in this situation and I found a great solution: the W3 Total Cache plugin and the MaxCDN service.

To get started, visit MaxCDN's site and set up an account. Their current promotion gives you 1TB of CDN bandwidth for one year for $10 (regularly $99). Once you sign up, do the following:

  • Click Manage Zones
  • Click Create pull zone

At this point, you'll see a list of form fields to complete:

  • Enter an alias for the pull zone name
  • The origin server URL is the URL that's normally used to access your site (i.e. rackerhacker.com)
  • The custom CDN domain is the URL you want to use for your CDN (i.e. cdn.rackerhacker.com)
  • The label can be anything you'd like to use to remember which zone is which
  • Enabling compression is generally a good idea

Once you save the zone, MaxCDN will give you a new domain name. You'll want to create a CNAME record that points from your CDN URL (for me, that's cdn.rackerhacker.com) to the really long URL that MaxCDN provides.

STOP HERE: Ensure that all of your DNS servers are replying with the CNAME record before you continue with the W3 Total Cache installation and CDN setup. If you proceed without waiting for that, some of your blog's visitors will get errors when they try to load content via your CDN domain.

You're ready for W3 Total Cache now. Install the plugin within your Wordpress installation and activate it. Hop into the settings for the plugin and make these adjustments:

  • Enable Page Caching and set it to Disk (enhanced)
  • Enable Minify and set it to Disk
  • Enable Database Caching and set it to Disk
  • Leave the CDN disabled for now, but flip the CDN Type to Origin Pull (Mirror)
  • Press Save changes

Click CDN Settings at the top of the page and configure the CDN:

  • Enter your CDN domain (for me, it's cdn.rackerhacker.com) in the top form field
  • Leave the other options as they are by default and click Save changes

W3 Total Cache should prompt you to clear out your page cache, and that would be recommended at this step. If you fully reload your blog's main page in your browser (may require you to hold SHIFT while you click reload/refresh) and check the page source, you should see your CDN URL appear for some of the javascript or CSS files.

You may discover that some CSS files, stylesheets, or images aren't being loaded via the CDN automatically. Luckily, that's an easy fix. Under the Minify Settings section of the W3 Total Cache plugin settings, scroll to the very bottom. Add in your javascript or CSS files via the form fields at the bottom and the plugin should handle the minifying (is that even a word?) and the CDN URL rewriting for you.

Further reading:


MySQL: The total number of locks exceeds the lock table size

This problem has cropped up for me a few times, but I've always forgotten to make a post about it. If you're working with a large InnoDB table and you're updating, inserting, or deleting a large volume of rows, you may stumble upon this error:

ERROR 1206 (HY000): The total number of locks exceeds the lock table size

InnoDB stores its lock tables in the main buffer pool. This means that the number of locks you can have at the same time is limited by the innodb_buffer_pool_size variable that was set when MySQL was started. By default, MySQL leaves this at 8MB, which is pretty useless if you're doing anything with InnoDB on your server.

Luckily, the fix for this issue is very easy: adjust innodb_buffer_pool_size to a more reasonable value. However, that fix does require a restart of the MySQL daemon. There's simply no way to adjust this variable on the fly (with the current stable MySQL versions as of this post's writing).

Before you adjust the variable, make sure that your server can handle the additional memory usage. The innodb_buffer_pool_size variable is a server wide variable, not a per-thread variable, so it's shared between all of the connections to the MySQL server (like the query cache). If you set it to something like 1GB, MySQL won't use all of that up front. As MySQL finds more things to put in the buffer, the memory usage will gradually increase until it reaches 1GB. At that point, the oldest and least used data begins to get pruned when new data needs to be present.

So, you need a workaround without a MySQL restart?

If you're in a pinch, and you need a workaround, break up your statements into chunks. If you need to delete a million rows, try deleting 5-10% of those rows per transaction. This may allow you to sneak under the lock table size limitations and clear out some data without restarting MySQL.

To learn more about InnoDB's parameters, visit the MySQL documentation.


Switching between audible and visual bells in screen

About a year ago, I was introduced to the joys of using irssi and screen to access irc servers. Before that time, I'd usually used graphical clients like Colloquy, and I always enjoyed getting Growl notifications when someone mentioned a word or string that I set up as a trigger.

Once I started using irssi in screen, I found that the visual bell in screen didn't get my attention quickly. Luckily, someone in the #slicehost channel let me know about screen's audible bell. You can flip between the visual and audible bell with CTRL-A and then CTRL-G. If you keep repeating that key combination, you'll switch back and forth between the two (with a status update at the bottom left).

You can also set up your visual bell configuration in your .screenrc via some configuration parameters:

vbell [on|off]
vbell_msg [message]
vbellwait sec

Crash course in dsh

Thanks to a recommendation from Michael and Florian, I've been using dsh with a lot of success for quite some time. In short, dsh is a small application which will allow you to run commands across many servers via ssh very quickly.

You may be wondering: "Why not just use ssh in a for loop?" Sure, you could do something like this in bash:

for i in`cat ~/myhosts.txt`; do ssh $i 'uptime'; done

But dsh allows you to do this:

dsh -g myhosts 'uptime'

In addition, dsh allows you to run the commands concurrently (-c) or one after the other (-w). You can tell it to prepend each line with the machine's name (-M) or it can omit the machine name from the output (-H). If you need to pass extra options, such as which ssh key to use, or an alternative port, you can do that as well (-o). All of these command line options can be tossed into a configuration file if you have a default set of options you prefer.

Another thing that makes dsh more powerful is the groups feature. Let's say you have three groups of servers - some are in California, others in Texas, and still others in New York. You could make three files for the groups:

  • ~/.dsh/group/california
  • ~/.dsh/group/texas
  • ~/.dsh/group/newyork

Inside each file, you just need to list the hosts one after the other. Here's the ~/.dsh/group/texas group file:

db1.tx.mydomain.com
db2.tx.mydomain.com
web1.tx.mydomain.com
web2.tx.mydomain.com
#web3.tx.mydomain.com

As you can see, dsh handles comments in the hosts file. In the above example, the web3 server will be skipped since it's prepended with a comment. Let's say you want to check the uptime on all of the Texas servers as fast as possible:

dsh -c -g texas 'uptime'

That will run the uptime command on all of the servers in the Texas group concurrently. If you need to run it on two groups at once, just pass another group (eg. -g texas -g california) as an argument. You can also run the commands against all of your groups (-a).

The dsh command can really help you if you need to gather information or run simple commands on many remote servers. If you find yourself using it often for systems management, you may want to consider something like puppet.


Change the escape keystrokes in screen

One of my favorite (and most used) applications on any Linux machine is screen. Once you fire up a screen session, you can start something and keep it running indefinitely. Even if your internet connection drops or you accidentally close your terminal window, the screen session will remain open on the remote server.

Detaching from a screen session is done by pressing CTRL-A and then d (for detach). However, when I'm on my Mac, CTRL-A and CTRL-E send my cursor to the beginning and end of lines, respectively. Once I launch screen, I lose the CTRL-A functionality because screen thinks I'm trying to send it a command.

Luckily, this can be changed in your ~/.screenrc:

escape ^Ww

With this change, you can press CTRL-W, then press d, and you'll detach from the screen session. For all of the screen options, run man screen on your local machine or review the man page online.