Tech Tips on DevCentral
   
You are here: Tutorials > Tech Tips

Current Articles | Categories | Search | Syndication

Hash Load Balancing and Persistence on BIG-IP LTM

by Deb Allen - 41095 views Article Rating
Alternate Rule for More Nodes

As previously noted, the requests per second are directly affected by the number of nodes. In order to improve upon the scalability, the iRule needs to be hashing the request against a smaller group of nodes at a time. The following example will step through 200 nodes distributed across multiple smaller pools of nodes.
  1. Instead of a single pool of 200 nodes, create 10 pools of 20 nodes each. Name the pools “pool_0”, “pool_1”, “pool_2” .… “pool_19”. The actual number of pools can be defined as per the iRule below.
  2. When a new request is made the iRule performs a simple URI hash and modulo calculation producing a number between 0 – 9. The rule uses this number to determine which pool to use.
  3. LTM performs the more expensive URI + Node IP hashing routine against the ten nodes within the chosen pool, rather than against the entire 100 nodes available.
Pros
  • This variation can accommodate any reasonable number of nodes
  • Adding nodes to existing pools maintains the minimal impact of Election Hash method
  • Easy to tune load to servers of varying disk and processor capacity. For instance, if one pool has 10 powerful servers, another pool has 20 smaller servers. On average, the servers in the second pool would receive half the load / unique requests.
Cons
  • If a node becomes unavailable, only the remaining nodes within the selected pool would divide the load. In the current example, the remaining 19 nodes would take over the requests for the missing node, rather than all 199.
  • Adding a new pool of nodes incurs the same drawbacks previously discussed with Typical Hashing. Specifically, this will reset the persistence distribution and should be done during an outage window with a controlled ramp up after making such a change. If the environment called for adding and removing large numbers of nodes seamlessly, it is possible to use the election hashing method to distribute across multiple pools and then use the election hashing method against the individual nodes within the pool. Performing this function twice will impact performance, but does allow for large scale changes in environments that are sensitive downtime.

Compound Election Hash iRule    (Requires version 9.4.2+.)
# Election Hash iRule
# Compound Compute Hash - MD5
#
# Basic hash picks a pool containing
# a subset of servers. Then perform
# election hash across pool members.
# Pools must be named Pool_<0-n>.
# Change % 10 to highest numbered pool.
#
# S = Current high score
# N = Node being evaluated
# W = Winning node
# P = Pool name
#
when HTTP_REQUEST timing on {
set S ""
binary scan [md5 [HTTP::uri]] i1 P
set P Pool_[expr $P % 10]
foreach N [active_members -list $P] {
if { [md5 $N[HTTP::uri]] > $S } {
set S [md5 $N[HTTP::uri]]
set W $N
}
}
pool $P member [lindex $W 0] [lindex $W 1]
}

(The current version of this iRule may be found in the codeshare here.)



Rate This Article:
Pages: 6 of 6 Previous Page

COMMENTS

posted @ Monday, June 23, 2008 7:19 AM by AndrewM   

I think the description above is incorrect, as it should be [md5 URL] % [pool_length] and not the other way around - the iRule at the bottom seems correct

posted @ Monday, June 23, 2008 7:19 AM by AndrewM   

(Typical hash section)

posted @ Monday, June 23, 2008 9:23 AM by Deb Allen   

Looks like you're right, I have corrected the initial equation. Thanks!
/deb

posted @ Wednesday, July 09, 2008 4:03 AM by Paul-Henri de Cathelineau   

HI,

I think the command :
expr [md5 [HTTP::uri]] % [active_members ]]

will not work, as the remainder operation (expr... % ...) requires that both arguments are Integer numbers.
The md5 command will return a binary or ascii string, so we should get messages like :

syntax error in expression ?? ?????????? ???? ??????B~ 6: character not legal in expressions while executing expr ...

So we need to convert the MD5 (or simply the HTTP URI) to a decimal (Integer) format.
Is there a way to do that ?

Thank you.

posted @ Friday, August 22, 2008 11:55 AM by Jeff Lord   

Yes i am having a similar issue....
Is there any way to work around?

TCL error: cache-persist HTTP_REQUEST - syntax error in expression àÈW¡¶[¢ð-ŸBš’ 2: character not legal in expressions while executing expr [md5 [HTTP::uri]] [active_members ehcache]

posted @ Monday, August 25, 2008 4:31 AM by AndrewM   

You may want to have a look at http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&postid=9834&view=topic

- The simple examples here had crc32 replaced with md5, but this didn't really work as md5 returns a string.

posted @ Tuesday, December 09, 2008 3:37 PM by Andy Litzinger   

It appears that you've ported some of the ideas from the CARP (http://icp.ircache.net/carp.txt) algorithm into an iRule. See section 3.1 'Hash Function'. Have you tried using the less CPU intensive CARP algorithm? It relies on a lightweight binary bit rotate rather than a CPU intense md5 call. While TCL doesn't have a built in bit rotate like C does, you can code an equivalent function to do it.

I'm not sure how to do it in TCL, but here is how I approached the bitwise rotate left in Perl (note, i'm not a programmer so expect ugly Perl).

sub Rotate_Left {
my $rlval =0;
# the passed in int to bit rotate
my $x = shift(@_);
# how many positions to rotate
my $n = shift(@_);
my $rval = $x << $n;
$rlval = ((($x) << ($n)) | (($x) >> (32-($n))));
return $rlval;
}

The rotate is only part of the CARP hash algorithm- the rest includes some further simple bit calculations that help to further randomize the node name/ip since they are often similar.The algorithm is clearly laid out in the RFC. I have more ugly Perl code for the whole algorithm if you're interested.

so while the iRule would be much longer and a bit more complicated, it (in theory) could be much more efficient and scalable. what do you think?

posted @ Tuesday, December 09, 2008 3:47 PM by Colin Walker   

That sounds very cool! I'll have to go browse around a bit and take a look.

Thanks!
#Colin

posted @ Thursday, August 06, 2009 1:27 PM by Paul   

One issue i have found with this is around object distribution.
If you have a reasonable number of caches, say around 30 and you use the example of:

[crc32 $CURRENT_NODE[HTTP::uri]]

You end up with a very large number of small objects residing on one cache, and if you lose that cache they all get redistributed to a single cache. favicon is a good example.

I am testing out this:

[crc32 $CURRENT_NODE[HTTP::host][HTTP::uri]]

It is more specific and seems to prevent this from occurring, it also adds minimal extra characters to the crc calculation.

On a secondary note however, I am not sure how far this will scale, the higher the volume of http transactions and larger the pool of node the more crc calculations you will have to do.

So a simple question is, with CMP will the iRule execute on separate TMM processes? So far i see the traffic flows on each of the TMM processes but the iRule is only executed in TMM0 which worries me a bit. Anyone have an idea on this?

NB. Ihave no persistance, ASM, Web Accelerator or global variables in the rule.

posted @ Monday, August 10, 2009 9:10 PM by Paul   

As an update to my earlier post:
It turns out that if you have one VIP forwarding to another both must be CMP capable.
If the first VIP is not then the second will not switch between TMM processes as this is one flow within that TMM and you are restricted to the same TMM.

posted @ Thursday, October 08, 2009 9:04 PM by NathanM   

It's been terrific to explore the world of consistent hashing and see how it can affect real world scenarios. I've had the chance to work with several dozen companies that have deployed this iRule with great success. Recognizing the popularity of this feature, F5 has incorporated the Election Hash concept into the native LTM code. You can now find this in v10 and later buried under Profiles > Persistence > Hash > Algorithm > CARP. Select this, create a small iRule (below) that finds the content you wish to hash upon, apply to your virtual server, and you are good to go. This will scale to vastly higher numbers of nodes with minimal CPU. Give it a try.

when HTTP_REQUEST {
persist hash [HTTP::uri]
}

posted @ Sunday, October 11, 2009 11:51 AM by Paul   

This is welcome news.
A couple of questions:
1. Is this for one pool of nodes only, it seems to be the case?
2. Is there a limit when you start to worry about the number of nodes?
3. What does higher numbers equate to in the F5 Lab?
4. What http request volume was it tested against?

I think ill run off now and try this out.



posted @ Wednesday, April 14, 2010 8:12 PM by danny tan   

there are about 420 members,1000 HTTP request per second,MD5 use 70% cpu and CRC32 use 50% cpu in 3600LTM,is there any way to use less cpu?
BTW:use uie persist only use 10% cpu.

posted @ Wednesday, April 14, 2010 8:45 PM by Paul   

Are you able to share your irule for this?
Are you doing 1 crc32 calc per node per request?

If you are then 50% cpu is very respectable and better than i can get with a viprion blade (85% for crc calcs) doing 8k requests/sec and only 30 nodes.

Have you tried the CARP persistence method at all that is in 10.1?

posted @ Wednesday, April 14, 2010 9:22 PM by danny tan   

the rule seems not difference.And I only run the rule on v947.because persit uie only run at tmm0,so I use the rule to run all traffice with cmp.but it seems that the rule use more cpu than persist uie,because there are too many members in pool. is there any way to run all the traffice better?

when HTTP_REQUEST {
set ucid_uri [findstr [HTTP::uri] "uid=" 5 "&"]
persist uie $ucid_uri 1200
}

when HTTP_REQUEST {
set ucid_uri [findstr [HTTP::uri] "uid=" 5 "&"]
set S ""
foreach N [active_members -list [LB::server pool]] {
if { [crc32 $N$ucid_uri] > $S } {
set S [crc32 $N$ucid_uri]
set W $N
# log local0. "the md5 is $S and pool is $W"
}
}
pool [LB::server pool] member [lindex $W 0] [lindex $W 1]
}

posted @ Wednesday, April 14, 2010 11:53 PM by NathanM   

If you have a finite and reasonable number of objects you could persist upon, then storing the persist table in memory is a great solution. As your numbers show, the 'persist uie' method is relatively inexpensive. Hashing, and especially consistent hashing such as CARP/Election Hash will incur higher CPU, but it provides other potentially important advantages such as unlimited number of persistable objects and multiple LTMs that can compute the same persistence results.

A small optimization that is often overlooked: the content you are looking to hash on is in the HTTP query, not the path portion of the URI. Changing [findstr [HTTP::uri] to [findstr [HTTP::query] will be more efficient as the LTM doesn't need to perform this operation on the entire URI. In this example: http://www.f5.com/folder1/index.html?uid=nathan&browser=firefox www.f5.com is the HTTP::host, folder1/index.html is the HTTP::path, and uid=nathan&browser=firefox is the HTTP::query. When doing a search against the HTTP::uri, the LTM is searching the path first, then the query.

In order to reduce the CPU overhead of consistent hashing, you can (and have) substituted MD5 for CRC32. All requests being equal, you'll find some lumpiness in the server utilization, but you'll shave ~30-50% CPU off the impact of running the iRule. Right now you are seeing 10% CPU with a simple rule doing memory based persistence. I'm guessing this rule is adding not much more than 1% CPU, and the rest is just the CPU required to push packets, load balance, provide protocol sanitization, etc. You are seeing 50% with CRC32 and 70% with MD5. So I'm again guessing that the iRule impact is ~1% for persist UIE, 40% CRC32, and 60% for MD5, plus 9.99% CPU for general load balancing overhead.

The real CPU hit is not from the number of requests per second, but the number of servers in the pool. The LTM is performing 420 hashes per request, and 1,000 reqs per second, or about 420,000 per second on your LTM 3600. That's a staggering number, and a real testament to just how fast the LTM really is to be able to accomplish this. An easy method for you to bring the CPU impact down is to use the 'compound election hash' method described at the end of this article. http://devcentral.f5.com/Default.aspx?tabid=63&PageID=153&ArticleID=135&articleType=ArticleView The idea is to break up your 420 servers into a number of smaller pools. So if you had 4 pools of 105 servers each and used the compound variant of the iRule, you would be performing 1 + 105 hashes per request, times 1,000 req/s, or 106,000 per second. If your MD5 hashing rule had an impact of 60% (plus 10% for LB), I would make a rough guess that you will see your total CPU at about 26% (a little over 15% for the MD5 rule + 10%). You could further lower that number by breaking up the servers into a greater number of pools.

The better answer is to upgrade to version 10. Yes, I know upgrades are a pain, but it's absolutely worth it for all the goodies and improvements it brings. v10 incorporates a similar variant of Election Hash into the kernal level code, and is insanely faster. You can still persist on any custom data using an iRule to find the data, and the built in Hash Persistence profile, which now has a new option to select the hash algorithm. You'd want to choose CARP (cache array routing protocol).
Here's an example of the iRule you'd use. You'll select this iRule in the Hash Persistence profile page.

when HTTP_REQUEST {
persist hash [findstr [HTTP::query] "uid=" 5 "&"]
}

A new 'persist carp' command, documented in the Wiki, has also been added into version 10.1 to make it easier to create and modify the Election Hash algorithm. This is not required if you are using the native Hash profile.

posted @ Thursday, April 15, 2010 12:12 PM by Paul   

Hash election or carp is most useful when you want to spread the cache load across a farm AND not have duplicate objects stored in each cache, thereby gaining the most benefit you can from the storage and processing power you have.
Another benefit i hadn't considered until Nathan pointed it out is that this behavior is consistent across physical LTM devices, so multiple active LTM's can help you to continue to scale if required. That is quite powerful.

Nathan i understand that its the crc calcs that are causing load what i cant understand is how a 3600 can do a staggering 420k/sec and a viprion blade cant do more than 70k/sec It seems incongruous.

We use the hash to select a pool (we have 3) and then a hash to select the node (10 in each pool), and so only do 13 crc requests/http request, when the farm is full we hit 85% cpu at ~7k req/sec so that is ~91k crc calc / sec. Which is by no means insignificant, but its far short of 420k @ 70% ;-).

I have modified the irule so that it is CMP capable and spread across all CPU cores as well.

The only thing that we are doing that is different is we are checking the TCP payload for the GET string before we send it to the hash election VIP, so it is a VIP targeting VIP. but this should be quite low in terms of processing required, i hope.

When you say it is 'insanely faster' have you seen any metrics on that? things like number of nodes tested etc.

Also can you still hash based on the pools imlimentation or do all nodes need to be in a single pool? This might be covered by 'persist carp' i think?

This is turning into a forum thread.. Ill post one later today.
Only registered users may post comments.
  
Subscriptions: Video  |  Audio  |  Tutorials  |  Tech Tips  |  Features  | 

More...

 

 

Essentials Quick Start Guides
iRules Wiki | iControl SDK | WebAccelerator Wiki iRules | iControl
FirePass Wiki | Advanced Design & Config Wiki WebAccelerator | FirePass

 

Videos

  

Audio

Cache in with LTM and iRules
Can iRules fix my cert mismatch errors?
Concurrent iControl Programming Explained
Cookie LoJack vi iRules
Creating An iControl PowerShell Monitoring Dashboard With Google Charts
Custom SNMP Traps
Exchange Persistence Duality and iRules
FTPS Offload via iRules
Getting Started with pyControl
iControl 101 - #19 - Time Conversions
iControl 101 - #20 - Port Lockdown
iControl 101 - #21 - Rate Classes
iControl 101 - #22 - GTM Data Centers
iControl Apps - #04 - Graceful Server Shutdown
iControl Apps - #05 - Rate Based Statistics
iControl Apps - #06 - Configuration Archiving
iControl Apps - #07 - System Http Statistics
iControl Apps - #08 - System IP Statistics
iControl Apps - #09 - TMM Statistics
iControl Apps - #10 - Bigpipe List
iControl Apps - #11 - Global GTM Statistics
iControl Apps - #12 - Global SSL Statistics
iControl Apps - #13 - System PVA Statistics
iControl Apps - #14 - Global Statistics
iControl Apps - #18 - Virtual Server Reverse Lookup
Investigating the LTM TCP Profile: Acknowledgements
Investigating the LTM TCP Profile: Congestion Control Algorithms
Investigating the LTM TCP Profile: ECN &amp; LTR
Investigating the LTM TCP Profile: Max Syn Retransmissions &amp; Idle Timeout
Investigating the LTM TCP Profile: Nagle’s Algorithm
Investigating the LTM TCP Profile: The Finish Line
Investigating the LTM TCP Profile: Windows &amp; Buffers
iRules 101 - #13 - TCL String Commands Part 1
iRules 101 - #14 - TCL String Commands Part 2
iRules 101 - #15 - TCL List Handling Commands
iRules Event Order
Managing The System Boot Location with iControl
Persisting SSL Connections
Replacing the WebSphere Apache Plugin with iRules
Ruby meets iControl: Creating VIPs
Ruby meets iControl: Making Wide IPs
Ruby Meets iControl: Switching Policies
Ten Steps to iRules Optimization
Unbind your LDAP servers with iRules
v.10 - A new iRules Namespace
v.10 - FastHTTP and Cookie Persistence
v.10 - iRules and the after command
v.10 - New class features in iRules
v.10 - Remote Authorization via TACACS&#43;
v10.1 - Configuring GTM's DNS Security Extensions

  

Features

  

Tutorials

  

iControl

  

iRules

  

Monitoring & Management

  

Advanced Design & Config

  

93,050 Members in 191 Countries and Growing!

Join DevCentral Today!

About DevCentral

F5 DevCentral is your source for the best technical documentation, discussion forums, blogs, media and more related to application delivery networking.

So dive in, meet your peers, and get familiar with DevCentral. We hope it makes your job easier and helps you get more from your F5 investment. If new to DevCentral, check out the Getting Started section. And if you have any problems, or think something could be easier to use, let us know.

Got It !

We've received your comment and transmitted it directly to DevCentral HQ.

Thanks for taking time to let us know what's on your mind. At DevCentral | Community Matters!

Get In Touch With Us

Have questions, suggestions or just want to get something off your chest?

Use our handy form below to Direct Connect with DevCentral Mission Control.

Send Us Feedback      or