From 1eb6c558083c2409588aa019fb8c90103b72d08a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 14 Dec 2018 08:33:28 +0100 Subject: [PATCH] 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. --- src/lb_fwlc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lb_fwlc.c b/src/lb_fwlc.c index ca422217e9..174dc67e69 100644 --- a/src/lb_fwlc.c +++ b/src/lb_fwlc.c @@ -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. - * Servers are sorted by #conns/weight. To ensure maximum accuracy, - * we use #conns*SRV_EWGHT_MAX/eweight as the sorting key. + * Servers are sorted by (#conns+1)/weight. To ensure maximum accuracy, + * 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. */ 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); } -- 2.39.5