MINOR: lb: make the leastconn algorithm more accurate

The leastconn algorithm queues available servers based on their weighted
current load. But this results in an inaccurate load balancing when weights
differ and the load is very low, because what matters is not the load before
picking the server but the load resulting from picking the server. At the
very least, it must be granted that servers with the highest weight are
always picked first when no server has any connection.

This patch addresses this by simply adding one to the current connections
count when queuing the server, since this is the load the server will have
once picked. This finally allows to bridge the gap that existed between
the "leastconn" and the "first" algorithms.
This commit is contained in:
Willy Tarreau 2018-12-14 08:33:28 +01:00
parent 7b8d203876
commit 1eb6c55808

View File

@ -43,14 +43,18 @@ static inline void fwlc_dequeue_srv(struct server *s)
} }
/* Queue a server in its associated tree, assuming the weight is >0. /* Queue a server in its associated tree, assuming the weight is >0.
* Servers are sorted by #conns/weight. To ensure maximum accuracy, * Servers are sorted by (#conns+1)/weight. To ensure maximum accuracy,
* we use #conns*SRV_EWGHT_MAX/eweight as the sorting key. * we use (#conns+1)*SRV_EWGHT_MAX/eweight as the sorting key. The reason
* for using #conns+1 is to sort by weights in case the server is picked
* and not before it is picked. This provides a better load accuracy for
* low connection counts when weights differ and makes sure the round-robin
* applies between servers of highest weight first.
* *
* The server's lock and the lbprm's lock must be held. * The server's lock and the lbprm's lock must be held.
*/ */
static inline void fwlc_queue_srv(struct server *s) static inline void fwlc_queue_srv(struct server *s)
{ {
s->lb_node.key = s->served * SRV_EWGHT_MAX / s->next_eweight; s->lb_node.key = (s->served + 1) * SRV_EWGHT_MAX / s->next_eweight;
eb32_insert(s->lb_tree, &s->lb_node); eb32_insert(s->lb_tree, &s->lb_node);
} }