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

