Forum Discussion
AndrewM_4835
Nimbostratus
Jun 11, 2008Hash Load Balancing
Dear Forum,
I am looking at trying an iRule to persistently load balance a group of web servers.
I have found an article 'Hash Load Balancing and Persistence on BIG-IP LTM' which does pretty much what I want to do - only I am running 9.2 on a pair of 6800s and the "active_members –list" does not exist.
when HTTP_REQUEST {
set picked [lindex [active_members –list test_pool] [expr [md5 [findstr [HTTP::uri] "SER=" 4 2]] % [active_members test_pool]]]
pool test_pool member [lindex $picked 0] [lindex $picked 1]
}
- but this doesn't work on 9.2
There are 12 servers in the test_pool, and I want all requests that have the same "SER=xx" to be sent to the same backend server...
Any suggestions?
(And please don't say upgrade)
Andrew
8 Replies
- The_Bhattman
Nimbostratus
Here is a piece of logic that may help.
192.168.1.x represents all the pool members in your test_pool.. . . set active_members { } set pool_list { 192.168.1.10 192.168.1.12 192.168.1.13 192.168.1.14 ... etc. } foreach node_address $pool_list { if {LB:status pool test_pool member $node_address eq "up" } { lappend active_members $N } } . . .
Least to say I don't like embedding IP addresses into iRule, but I thought it might get you in the right direction and hopefully the iRule pro's in this forum would jump in enhance it or simply figure out a better way. I would also investigate using classes to replace the IP address simply because it's cleaner.
I hope this helps,
CB - Mark_Melin_6298
Nimbostratus
I got this kind of thing working nicely, however, i am on 9.4.3 so....
http://devcentral.f5.com/Default.aspx?tabid=53&forumid=31&view=topic&postid=23963 - AndrewM_4835
Nimbostratus
The solution with checking which nodes are currently active myself seems a little slow - and I can't imagine it scales very well...
I originally tried "persist uie", but the problem I had is that initially, should one server go down, all load would be split across the remaining servers BUT when I bring the broken server back up, it no longer gets any traffic as all '100' different values are mapped to the other servers until a timeout happens.
This is even worse during a complete restart, because with stupid luck, 1 of the 4 servers may get ALL the traffic.
Does persist hash not also have the same problem? - The_Bhattman
Nimbostratus
If you refering to the one I posted, I have already tried this on a ~100,000 connections/sec and apparently it works just fine. What doesn't scale well is adding the multiple IP addresses. However, if you see that it's slowing you down then it's possible that it's plateform dependent performance OR settings dependent. Currently, I am using it on several 8400s and 6400 LTM. - AndrewM_4835
Nimbostratus
In LTM 9.2.4 md5 returns a string and not a number - is this different in 9.4?
which is why
set test [ [ expr [md5 {[findstr [HTTP::uri] "SRV=" 4 2]} ] % [llength $active_server_list] ]]
doesn't work.
where string looks like http://.../blubber?SRV=xx where xx is a number between 00 and 99.
I also tried using crc32 - but I found that with only 100 different possibilities, it didn't spread the load evenly enough.
My rule so far without checking for an empty string in SRV, or that they aren't numbers between 00 and 99, and that at least one server is working:when HTTP_REQUEST { log local0. "Request: [HTTP::uri]" set search_server_list { {10.0.164.11 20001} {10.0.164.11 20002} {10.0.164.11 20003} } set active_server_list {} foreach node_address $search_server_list { if { [LB::status pool search_hash_pool member [lindex $node_address 0] [lindex $node_address 1]] eq "up" } { lappend active_server_list $node_address } } set picked [ lindex $active_server_list [expr {[findstr [HTTP::uri] "SRV=" 4 2]} % {[llength $active_server_list]}] ] pool search_hash_pool member [lindex $picked 0] [lindex $picked 1] }
I tried adding the set search_server_list to RULE_INIT, but unfortunately no longer had access to it in the event, which means I need to reset its value every HTTP_REQUEST event....
After doing all of this, I will probably upgrade to 9.4.x as this all feels nasty - haven't had a chance to performance test it yet though.
Any thoughts or comments?
Thanks
Andrew - AndrewM_4835
Nimbostratus
Modified version with error checkingwhen HTTP_REQUEST { set search_server_list { {10.0.164.11 20001} {10.0.164.11 20002} {10.0.164.11 20003} } set active_server_list {} foreach node_address $search_server_list { if { [LB::status pool search_hash_pool member [lindex $node_address 0] [lindex $node_address 1]] eq "up" } { lappend active_server_list $node_address } } if {[catch {set server_number [expr {[findstr [HTTP::uri] "SRV=" 4 2]} % {[llength $active_server_list]}] }]} { pool search_hash_pool } else { set picked [ lindex $active_server_list $server_number ] pool search_hash_pool member [lindex $picked 0] [lindex $picked 1] } }
Now all that remains is to test the performance.
Thanks all for your help.
Regards
Andrew - AndrewM_4835
Nimbostratus
This rule has been up and running for about a month now.
After enabling this rule on a pair of 6800s I saw NO jump in the CPU usage on the boxes -
FYI: I have about 50 req/s on this rule.
So the great news is - it works and is usable.
Cheers
Andrew - Patrick_Chang_7Historic F5 Accountmd5 produces a string. You can use the binary scan command to convert this to an integer. see the election hash iRule to see how this works.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects