Forum Discussion
papalukg_33581
Nimbostratus
Jul 17, 2008Hashing load balancing and persistence
Hi all,
In our case we have a server pool and our main goal is that the traffic generated by the same clients must be always assigned to the same pool members. For this reason, we have implemented hash load balancing over the members of this pool. However, we need to hold a persistence table. The reason for the persistence table is that when a pool member goes down and its traffic is reassigned to another node the traffic should continue to pass through this node even if the faulty node comes up. This way the loss from "switching" traffic can be minimum.
Up to now we have implemented the example from hhttp://devcentral.f5.com/Default.aspx?tabid=63&PageID=151&ArticleID=135&articleType=ArticleView . The differences are that we use the event CLIENT_ACCEPTED and instead of HTTP::uri, we use IP::client_addr. Our problem is that we cannot add at the same time, entries to the persistence table according to the selection algorithm. Can anyone offer some help or suggest a different way?
- The_Bhattman
Nimbostratus
The following is something I quickly wrote for a developer who wanted something simiiliar in that he wanted to the traffic to continue w/o having it "switch" when the faulty node came back up. This was written in v9.3.1 so I couldn't use the "active_members -list " command. This might exactly answer your question but it might help you think of solving your problem in a different way.This iRULE requires each pool have 1 member, and the last pool has all the combined members and it is equally balanced or prioritized. The goal is when a client enters http://your.domain.com/?sid=P01 it will be directed to a specific pool. If there is no URI, then look for a user-name in the http-header that that information and use CRC32 and create HASH number. That number will be used to direct clients to a specific pool. If there is no URI or user-name then do standard load balancing. when HTTP_REQUEST { This IF statement queries the URI to look for PO after a ? if { [HTTP::query] contains "P0" } { Takes the URI after ? skips 5 characters and sends the rest of the string to a variable. For example, URI = /?sid=P01. Looks at everything after ?, skips sid=P, scans the next 2 charcters/numbers and sends the characters to the variable serverid. set serverid [substr [HTTP::query] 5 2] If another node is added to opentv, another pool statement must be added to the switch statement. switch $serverid { 01 { pool pool_foobar.foo.com_01 } 02 { pool pool_foobar.foo.com_02 } 03 { pool pool_foobar.foo.com_03 } 04 { pool pool_foobar.foo.com_04 } } } This statement checks to see if the is a user-name" elseif { [HTTP::header exists "user-name"] } { This creates a unique number using crc32 based on user-name in the http header and assigns it to a variable. This unique number is passed to poolnum set poolnum [crc32 [HTTP::header "user-name"]] The following takes poolnum variable, divides it by 4 and assigns the remainder to poolnum. This will result in the following answers 0,1,2,3. If you divded by 5 then it's 0,1,2,3,4, etc,. 4 is equal to the total of nodes in pool_foobar.foo.com_lb. If a node is added then you must increment by N number of nodes that were added. I.E., if 2 nodes are added then 4 + 2 = 6. set poolnum [expr $poolnum % 4 ] Increment the poolnum because we want a number higher then 0 to associate to a pool name. incr poolnum If another node is added to application, another pool statement must be added to the switch statement switch $poolnum { 1 { pool pool_foobar.foo.com_01 } 2 { pool pool_foobar.foo.com_02 } 3 { pool pool_foobar.foo.com_03 } 4 { pool pool_foobar.foo.com_04 } } } } Triggered when the selected server fails in the selected pool, all connections on the failed node will be forced to reparticipate in load balancing. when LB_FAILED { if { [HTTP::header exists "user-name"] } { set GOOD_NODES {} When adding node then you must add the member node to NS set NS {192.168.0.202 192.168.0.203 192.168.0.204 192.168.0.205} foreach N $NS { if { [LB::status pool pool_foobar.foo.com_lb member $N 8080] eq "up" } { lappend GOOD_NODES $N } } set NODENUM [crc32 [HTTP::header "user-name"]] set NODENUM [expr $NODENUM % [active_members pool_foobar.foo.com_lb] ] LB::reselect pool pool_foobar.foo.com_lb member [lindex $GOOD_NODES $NODENUM] } else { pool pool_foobar.foo.com_lb LB::reselect } }
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