mirror of
https://github.com/haproxy/haproxy.git
synced 2026-05-21 01:15:17 -04:00
MINOR: backend: support hash-key guid for a stabler distribution
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
When server fleets are constantly updated, using a stable distribution across a bunch of load balancers can be convenient. The addr and port already provide a bit of this but for situations were addresses might differ between sites or change dynamically this does not work. The guid is perfect for this because by definition it's supposed to designate a single server and be unique. So when two servers anywhere have the same, the tool that provisionned them promises that they are the same server. So here we introduce "hash-key guid" which performs a 32-bit hash on the GUID value. When no guid is provided, a fallback is performed on ID, as is done for other keys.
This commit is contained in:
parent
a59e6e5efd
commit
7004bb3b8c
4 changed files with 23 additions and 2 deletions
|
|
@ -18859,6 +18859,12 @@ hash-key <key>
|
|||
assigned ID values that are evenly distributed over the 32-bit
|
||||
space.
|
||||
|
||||
guid The node keys will be derived from the server's guid, when
|
||||
available, otherwise they will fall back on "id". The benefit
|
||||
is that it does not depend on ordering at all, only on an
|
||||
internal stable identifier that can be replicated across many
|
||||
load balancers.
|
||||
|
||||
addr The node keys will be derived from the server's address, when
|
||||
available, or else fall back on "id".
|
||||
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ struct pid_list {
|
|||
enum srv_hash_key {
|
||||
SRV_HASH_KEY_ID = 0, /* derived from server puid, 28 LSB used */
|
||||
SRV_HASH_KEY_ID32, /* derived from server puid, 32 bits used */
|
||||
SRV_HASH_KEY_GUID, /* derived from server guid */
|
||||
SRV_HASH_KEY_ADDR, /* derived from server address */
|
||||
SRV_HASH_KEY_ADDR_PORT /* derived from server address and port */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <haproxy/api.h>
|
||||
#include <haproxy/backend.h>
|
||||
#include <haproxy/errors.h>
|
||||
#include <haproxy/guid.h>
|
||||
#include <haproxy/queue.h>
|
||||
#include <haproxy/server.h>
|
||||
#include <haproxy/tools.h>
|
||||
|
|
@ -82,6 +83,7 @@ static inline u32 chash_compute_server_key(struct server *s)
|
|||
{
|
||||
enum srv_hash_key hash_key = s->hash_key;
|
||||
struct server_inetaddr srv_addr;
|
||||
const char *guid_key = NULL;
|
||||
u32 key;
|
||||
|
||||
/* If hash-key is addr or addr-port then we need the address, but if we
|
||||
|
|
@ -96,6 +98,11 @@ static inline u32 chash_compute_server_key(struct server *s)
|
|||
}
|
||||
break;
|
||||
|
||||
case SRV_HASH_KEY_GUID:
|
||||
guid_key = guid_get(&s->guid);
|
||||
if (!guid_key)
|
||||
hash_key = SRV_HASH_KEY_ID;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -121,6 +128,10 @@ static inline u32 chash_compute_server_key(struct server *s)
|
|||
}
|
||||
break;
|
||||
|
||||
case SRV_HASH_KEY_GUID:
|
||||
key = XXH32(guid_key, strlen(guid_key), 0);
|
||||
break;
|
||||
|
||||
case SRV_HASH_KEY_ID32:
|
||||
key = full_hash(htonl(s->puid));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1015,7 +1015,7 @@ static int srv_parse_hash_key(char **args, int *cur_arg,
|
|||
struct proxy *curproxy, struct server *newsrv, char **err)
|
||||
{
|
||||
if (!args[*cur_arg + 1]) {
|
||||
memprintf(err, "'%s expects 'id', 'id32', 'addr', or 'addr-port' value", args[*cur_arg]);
|
||||
memprintf(err, "'%s expects 'id', 'id32', 'guid', 'addr', or 'addr-port' value", args[*cur_arg]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
|
|
@ -1025,6 +1025,9 @@ static int srv_parse_hash_key(char **args, int *cur_arg,
|
|||
else if (strcmp(args[*cur_arg + 1], "id32") == 0) {
|
||||
newsrv->hash_key = SRV_HASH_KEY_ID32;
|
||||
}
|
||||
else if (strcmp(args[*cur_arg + 1], "guid") == 0) {
|
||||
newsrv->hash_key = SRV_HASH_KEY_GUID;
|
||||
}
|
||||
else if (strcmp(args[*cur_arg + 1], "addr") == 0) {
|
||||
newsrv->hash_key = SRV_HASH_KEY_ADDR;
|
||||
}
|
||||
|
|
@ -1032,7 +1035,7 @@ static int srv_parse_hash_key(char **args, int *cur_arg,
|
|||
newsrv->hash_key = SRV_HASH_KEY_ADDR_PORT;
|
||||
}
|
||||
else {
|
||||
memprintf(err, "'%s' has to be 'id', 'id32', 'addr', or 'addr-port'", args[*cur_arg]);
|
||||
memprintf(err, "'%s' has to be 'id', 'id32', 'guid', 'addr', or 'addr-port'", args[*cur_arg]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue