As discussed in the patch, there is a bug in the hash-balance-factor logic 
which can cause a server to get more load than hash-balance-factor would allow, 
if a request hashes to a point in the hash ring where the server in question 
has two consecutive entries. The impact isn't great but it does allow a 
violation of the load-balancing guarantee that hash-balance-factor is supposed 
to provide, so here is a fix. Patch against master, also applies against 1.7. 
Not applicable to earlier versions since hash-balance-factor was added with 1.7.


Andrew
From 197e08ad87b1dcad6cf99d825227f6fb8141e797 Mon Sep 17 00:00:00 2001
From: Andrew Rodland <[email protected]>
Date: Wed, 26 Apr 2017 02:57:03 -0400
Subject: [PATCH] BUG/MINOR: hash-balance-factor isn't effective in certain
 circumstances

in chash_get_server_hash, we find the nearest server entries both
before and after the request hash. If the next and prev entries both
point to the same server, the function would exit early and return that
server, to save work.

Before hash-balance-factor this was a valid optimization -- one of nsrv
and psrv would definitely be chosen, so if they are the same there's no
need to choose between them. But with hash-balance-factor it's possible
that adding another request to that server would overload it
(chash_server_is_eligible returns false) and we go further around the
ring. So it's not valid to return before checking for that.

This commit simply removes the early return, as it provides a minimal
savings even when it's correct.
---
 src/lb_chash.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/lb_chash.c b/src/lb_chash.c
index 84a2ef36e..2394baa12 100644
--- a/src/lb_chash.c
+++ b/src/lb_chash.c
@@ -306,10 +306,8 @@ struct server *chash_get_server_hash(struct proxy *p, unsigned int hash)
 
 	nsrv = eb32_entry(next, struct tree_occ, node)->server;
 	psrv = eb32_entry(prev, struct tree_occ, node)->server;
-	if (nsrv == psrv)
-		return nsrv;
 
-	/* OK we're located between two distinct servers, let's
+	/* OK we're located between two servers, let's
 	 * compare distances between hash and the two servers
 	 * and select the closest server.
 	 */
-- 
2.11.0

Reply via email to