In my role as an ADC I often get to run customer labs – this is where we take a customers application, install it on the hardware we have in Reading, and then exercise a number of load tests against it to see what opportunities there are for performance and scalability tweaking.

Just before Christmas I was in the labs with one of my customers who have a high-profile site due to go live in a few months. I’ve been working with them for about 18 months and they now have a really scalable architecture which, based on the numbers we got in the labs, should deal with all the load likely to be chucked at it.

Anyhow, one of the new bits of kit I got to play with this time was a Big-IP box from F5. It’s a hardware load balancer and I must say I was very impressed with its capabilities so thought I should blog about it.

First off, a picture of the architecture :-


At the top we have our load injectors – there were 8 of these during testing. Each request goes through the Big-IP box which executes code against the request (known as an iRule, more on those in a bit), and then the request ends up on one ‘node’ or another – here ‘node’ applies to a group of servers, in our case containing four physical servers and a local database server. Then we have the main database behind the scenes – we were using SQL Service Broker for communication between the node database and the back-end database.

Now, the reason we were using this load balancer wasn’t just to balance load – based on the way the system was setup we wanted to partition requests based on some criteria, as in actuality we had partitioned user data across the nodes. A simplistic example would be all users with surnames ‘A’ - ‘M’ would be redirected to node 1, all others to node 2. Originally we had some code on the nodes which would decide if the request was appropriate for the node it had come in to, and if not pass it on to the appropriate node. However, with the Big-IP box we were able to make this choice on the load balancer itself, thus minimising the code on the nodes and also simplifying any changes that might need to be made into one place. It’s possible to partition load based on any criteria you can think up – maybe geographical (load from South Africa goes to a server in Johannesburg, load from the UK goes to a node in Manchester), maybe based on availabilty (the last request to node1 timed out, so try node 2 for now), or a host of other criteria.

In order to do our partitioning scheme we had to write an iRule. An iRule is some code that is executed on the Big-IP box on a given event – it uses a fairly simple yet powerful syntax (based on a version of TCL) which is tailored to suit the environment. There are custom commands that have been added to the language by F5, and some standard TCL commands have been removed too. The language is targeted to do one thing well – and this it does! The iRule is compiled and is then executed based on the particular event or events it has been defined for. For a definition of the events you can handle see here.

The rule we came up with was as follows :-

  log local0. "in HTTP_REQUEST"
  if {[HTTP::uri] starts_with "/node1"}
    pool Pool1;
    log local0. "pool1 selected"
    #Remove node1 from the uri
    set uri [string range $uri 4 end]
    HTTP::uri $uri
  elseif {[HTTP::uri] starts_with "/node2"}
    pool Pool2;
    log local0. "pool2 selected"
    #Remove node1 from uri
    set uri [string range $uri 4 end]
    HTTP::uri $uri
This just checks the incoming URL for either ‘/node1’ or ‘/node2’ and then chooses an appropriate pool to direct that request to using the pool statement. As the URI includes the node we also wished to remove this from the URI before forwarding the request – so there’s a little string manipulation going on here too. The log statement emits debug information which can be viewed as necessary in a separate console – this comes in handy when you are writing the rule to ensure it’s doing what you need.
When a request turns up on the Big-IP box it goes through the following pipeline :-
As you can see you can plug in an iRule at any stage in the request processing. You can also do stuff without requiring code – such as caching frequently used pages or images so that the request never touches your actual server. The Big-IP box has some fairly beefy hardware inside so whilst rules are executing in x86 assembly language, some parts of the processing are offloaded to specialized hardware – such as SSL processing.
For some further information on iRule development see the F5 devcentral site – which has loads of examples and is really useful when you’re trying to learn how to construct rules. Chances are there’s one up there you can re-use rather than writing a new one! There’s even a .NET API you can use to talk to the Big-IP box, and also PowerShell access if that’s your thing.
All in all I was very impressed!
Originally posted by Morgan Skinner on January 14th 2009 here.