Forum Discussion

Funkdaddy's avatar
Icon for Nimbostratus rankNimbostratus
Jul 10, 2020

Load Balancing Based on ID in Path and Modulus of Available Servers



We have a use case for delivering MPEG-DASH streams from a pool of Wowza Edge servers for many different events at once. Ideally, all users requesting a certain event_id will be sent to the same edge server so that all the Edge servers won't need to serve content from all concurrent events. Note the MPEG-DASH "stream" is just a series of HTTP requests from a player in the browser for manifest and segment files.


I have an HTTPS VIP using tcp and http profiles and a defined pool of all Edge Severs. I have already constructed an iRule that will assign each event_id to certain Edge server (node in the pool) based on a modulus of available servers in the pool. Additionally I set a local variable that keeps track of the current node, so that once the value is set it doesn't have to figure out which node to send to for the future requests that come in on the same HTTP connection.


This is actually working fine for normal operation. The problem we are trying to solve is if one Edge server goes down, that only the events on the downed member get sent to a new server based on the (now diminished by 1) number of available servers, while all other requests continue to go to their originally selected server. I.E. we don't want one server down to re-balance ALL events across all the pool members.


Theoretically, I thought that each stream to each end user would use a single HTTP session and trigger only one CLIENT_ACCEPTED event and then be followed by HTTP_REQUEST events in which the local variable defining the node would stay the same and those connections on pool members that didn't go down would stay stuck to their respective server.


However, what I'm seeing is that a single HTTP stream will issue a new CLIENT_ACCEPTED event one out of every 8-10 requests, which will then trigger another load balancing decision. Thus if a server goes down, existing streams might continue for some short period of time on the selected pool member, but will re-balance each stream when the CLIENT_ACCEPTED event is triggered on each running stream.


Note that the MPEG-DASH player does NOT seem to honor cookies (e.g. persistence cookies).



* Is my reasoning flawed that each stream would continue to use the same HTTP stream?

* What would cause a new CLIENT_ACCEPTED event in an apparently active HTTP session? Is this related to the server's Keep-Alive settings?

* Is there a way to ensure each HTTP stream is contained in a single session?

* Is there a better way to ensure that each event_id's streams get allocated to only one server in the pool? I've contemplated using a Data Group to map each event ID to a node, but not sure what the overhead of writing and reading to the DG will have on overall performance.





iRule Below:


	set default_pool [LB::server pool]
	set default_node "NULL"
	if { $default_node eq "NULL" } {
		#get sorted list of active members in pool
		set members [lsort [active_members -list $default_pool]]
		#extract event_id from URL path
		set evtid <<<code to extract event_id from URL Path here>>>
		#select node based on modulus of event_id by the number of available pool members
		set selectednode [lindex $members [expr { $evtid % [llength $members] } ] ]
		#replace " " with ":" for use in "node" command
		set default_node [string map { " " ":" } $selectednode]
	node $default_node

1 Reply

  • PS it occurs to me a Data Group wouldn't be a possible solution here since the rule needs to write - a Table would be the way to maintain Event-Node mapping for use in other sessions.