Subscriptions: Video  |  Audio  |  Tutorials  |  Tech Tips  |  Features  |  More...

Current Articles | Categories | Search | Syndication

by deb - 22895 views Article Rating
Election Hash

Instead of a single calculation to determine node position, the requested content plus the node IP addresses are calculated. The LTM numerically ranks the resulting answers across all available nodes, similar to an election. So instead of a single calculation, a separate calculation is made for each of the possible nodes in the pool.

Typical hash algorithm:
       Selected Node = Position-In-Pool = [Number-Of-Pool-Members % [md5 [ URI ]]]

Election hash algorithm:
      Selected Node = Highest-Node-Score = [md5 [Node-IP-Address + URI ]]

A given node will always attain the same score for a unique object regardless of its order within the pool. This calculation is performed for every member within the pool, using its unique IP within the calculation. The request is sent to the node with the highest “score”, highlighted in yellow in the following examples.

Figure 1.3
  url_1 url_2 url_3url_4
172.29.4.53 8 4 5 0
172.29.4.54 2 9 1 7
172.29.4.55 7 0 7 6
172.29.4.56 4 4 6 8

Figure 1.4
  url_1 url_2 url_3url_4
         
172.29.4.54 2 9 1 7
172.29.4.55 7 0 7 6
172.29.4.56 4 4 6 8

Compare figures 1.3 and 1.4. The formula has not changed, so each remaining node would calculate the same answer. The request for url_1 can’t be won by the .53 server since it has been disabled, so the next highest answer will be from the .55 node. The only traffic shift that would occur is for requests that had previously been directed to the .53 node. Requests for other content remain unaffected by the pool membership change.

Figure 1.5
  url_1 url_2 url_3url_4
172.29.4.53 8 4 5 0
172.29.4.54 2 9 1 7
172.29.4.55 7 0 7 6
172.29.4.56 4 4 6 8
172.29.4.57 3 3 9 2

When a new node is added to the pool it would participate in the numeric election system. In figure 1.5, the new .57 node would take over an average of %20 of the requests. The only traffic shift that would occur is for elections the .57 node has now won.
This system scales infinitely to the number of unique requests that can be made by a client. Pool membership changes from adding, removing, enabling, or disabling a node will have no greater effect on the remaining members other than the assumption of relinquishment of its portion of the traffic.

Pros
  • Scales to infinite number of requested objects
  • Gracefully handles pool membership changes
Cons
  • Instead of one calculation per request, the LTM must perform one calculation per request per node

Election Hash iRule:    (Note: this rule requires version 9.4.2+. Change <pool> to your pool name.
 # Election Hash iRule 
# Compute Hash - MD5
#
# MD5 calculation of Server + URI
# Rule selects Server that scores highest
#
# S = Current high score
# N = Node being evaluated
# W = Winning node
#
when HTTP_REQUEST timing on {
set S ""
foreach N [active_members -list <pool>] {
if { [md5 $N[HTTP::uri]] > $S } {
set S [md5 $N[HTTP::uri]]
set W $N
}
}
pool <pool> member [lindex $W 0] [lindex $W 1]
}
(The current version of this iRule may be found in the codeshare here.)

LTM sample log results with four nodes active in the pool:
Rule: Node: 172.29.4.53/32 Score: 917
Rule: Node: 172.29.4.54/32 Score: 67
Rule: Node: 172.29.4.55/32 Score: 74
Rule: Node: 172.29.4.56/32 Score: 577
Rule: Picked Node: 172.29.4.53 URI: /images/logo.gif Highest Score: 917
The results when node .53 is unavailable:
Rule: Node: 172.29.4.54/32 Score: 67
Rule: Node: 172.29.4.55/32 Score: 74
Rule: Node: 172.29.4.56/32 Score: 577
Rule: Picked Node: 172.29.4.56 URI: /images/logo.gif Highest Score: 577
The iRule correctly scored each possible node against the object requested and selected the highest scoring server. Removing a node only affected traffic which that node had previously won.


Next Section: How Does Election Scale?


Rate This Article:
Pages: 4 of 6 Previous Page Next Page

COMMENTS

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 andrewm42


(Typical hash section)

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


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

posted @ Monday, June 23, 2008 9:23 AM by deb


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 @ Wednesday, July 09, 2008 4:03 AM by paul-henri.decathelineau


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 @ Friday, August 22, 2008 11:55 AM by jlord13


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 @ Monday, August 25, 2008 4:31 AM by andrewm42


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:37 PM by andy.litzinger@theplatform.com


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

Thanks!
#Colin

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


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 @ Thursday, August 06, 2009 1:27 PM by paul.tinson


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 @ Monday, August 10, 2009 9:10 PM by paul.tinson


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 @ Thursday, October 08, 2009 9:04 PM by nathanmcmahon


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 @ Sunday, October 11, 2009 11:51 AM by paul.tinson


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:12 PM by dannyhltan


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 8:45 PM by paul.tinson


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 9:22 PM by dannyhltan


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 @ Wednesday, April 14, 2010 11:53 PM by nathanmcmahon


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.

posted @ Thursday, April 15, 2010 12:12 PM by paul.tinson


posted @ Sunday, April 25, 2010 11:54 PM


Audio
Validating Data Group (Class) References
v10.1 - Configuring GTM's DNS Security Extensions
v.10 - Remote Authorization via TACACS+
v.10 - New class features in iRules
v.10 - iRules and the after command
v.10 - FastHTTP and Cookie Persistence
v.10 - A new iRules Namespace
Unbind your LDAP servers with iRules
Ten Steps to iRules Optimization
Tech Tip: Saving Your iControl Changes
Switch Gone Wild: Using Wildcards with the Tcl "switch" command
Stacking iRules: A Modular Approach
SNMP: Capturing SSL Statistics per Virtual Server
Selective DNS Persistence on GTM
Ruby Meets iControl: Switching Policies
Ruby meets iControl: Making Wide IPs
Ruby meets iControl: Creating VIPs
Rewriting Redirects
Replacing the WebSphere Apache Plugin with iRules
RADIUS Load Balancing with iRules
Polymorphism - Making TCL operators work for you
Persisting SSL Connections
Persisting Across Virtual Servers
Passive Application Monitoring with LTM
Monitoring TCP Applications #01
Managing The System Boot Location with iControl
LTM: Per-VLAN Default Gateways
LTM: Dueling Timeouts
LTM: Configuring IP Forwarding
LTM: Action on Service Down
iRules: Disabling Event Processing
iRules Update: New options for the "log" command
iRules Optimization 101 - #05 - Evaluating iRule Performance
iRules Optimization 101 - #04 - Delimiters: Braces, Brackets, Quotes and more
iRules Optimization 101 - #03 - for vs. foreach
iRules Optimization 101 - #02 - Expressions and Variables
iRules Optimization 101 - #01 - if, elseif and switch
iRules Event Order
iRules 101 - #15 - TCL List Handling Commands
iRules 101 - #14 - TCL String Commands Part 2
iRules 101 - #13 - TCL String Commands Part 1
iRules 101 - #12 - Validating Your Logic
iRules 101 - #11 - Events
iRules 101 - #10 - Regular Expressions
iRules 101 - #09 - Debugging
iRules 101 - #08 - Classes
iRules 101 - #07 - Catch
iRules 101 - #06 - When
iRules 101 - #05 - Selecting Pools, Pool Members, and Nodes
iRules 101 - #04 - Switch
iRules 101 - #03 - Variables
iRules 101 - #02 - If and Expressions
iRules 101 - #01 - Introduction to iRules
iRule Security 101 - #09 - Command Execution
iRule Security 101 - #08 - Limiting POST Data
iRule Security 101 - #07 - FTP Proxy
iRule Security 101 - #06 - HTTP Referer
iRule Security 101 - #05 - Avoiding Path Traversal
iRule Interference: Custom Closes and Responses
Investigating the LTM TCP Profile: Windows & Buffers
Investigating the LTM TCP Profile: The Finish Line
Investigating the LTM TCP Profile: Nagle’s Algorithm
Investigating the LTM TCP Profile: ECN & LTR
Investigating the LTM TCP Profile: Congestion Control Algorithms
Investigating the LTM TCP Profile: Acknowledgements
iControl Concept to Implementation (iC2I): The Introduction.
iControl Apps - #18 - Virtual Server Reverse Lookup
iControl Apps - #14 - Global Statistics
iControl Apps - #13 - System PVA Statistics
iControl Apps - #12 - Global SSL Statistics
iControl Apps - #11 - Global GTM Statistics
iControl Apps - #10 - Bigpipe List
iControl Apps - #09 - TMM Statistics
iControl Apps - #08 - System IP Statistics
iControl Apps - #07 - System Http Statistics
iControl Apps - #06 - Configuration Archiving
iControl Apps - #05 - Rate Based Statistics
iControl Apps - #04 - Graceful Server Shutdown
iControl Apps - #03 - Local Traffic Map
iControl Apps - #02 - Local Traffic Summary
iControl Apps - #01 - Disabling Node Servers
iControl 101 - #22 - GTM Data Centers
iControl 101 - #21 - Rate Classes
iControl 101 - #20 - Port Lockdown
iControl 101 - #19 - Time Conversions
iControl 101 - #18 - Stream Profile
iControl 101 - #17 - PortMirror
iControl 101 - #16 - SelfIPs
iControl 101 - #15 - System Services
iControl 101 - #14 - License Administration
iControl 101 - #13 - Data Groups
iControl 101 - #12 - Database Variables
iControl 101 - #11 - Performance Graphs
iControl 101 - #10 - System Inet
iControl 101 - #09 - iRules
iControl 101 - #08 - Partitions
iControl 101 - #07 - User Management
iControl 101 - #06 - File Transfer APIs
iControl 101 - #05 - Exceptions
iControl 101 - #04 - Language Options
iControl 101 - #03 - iControl Taxonomy
iControl 101 - #02 - How iControl Works
iControl 101 - #01 - iControl Marketing Dissected
iC2I: Automation - Creating Virtuals Simplified.
GTM, Know Thyself
Getting Started with pyControl
FTPS Offload via iRules
Exchange Persistence Duality and iRules
Dynamic WSDL updating with iRules
Custom SNMP Traps
Creating An iControl PowerShell Monitoring Dashboard With Google Charts
Cookie LoJack vi iRules
Content-Disposition - Forced file downloads via HTTP
Concurrent iControl Programming Explained
Case Insensitive Comparisons
Can iRules fix my cert mismatch errors?
Cache in with LTM and iRules
Building a Custom WebAccelerator Policy
Automated Web Analytics iRule Style
Investigating the LTM TCP Profile: Max Syn Retransmissions & Idle Timeout