diff --git a/doc/configuration.txt b/doc/configuration.txt index c430a4796..ed0573165 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -18850,6 +18850,15 @@ hash-key better only use values comprised between 1 and this value to avoid overlap. + id32 The node keys will be derived from the server's numeric + identifier as set from "id" or which defaults to its position + in the server list, but the full 32 bits of the ID will be + used so that there is no collision. This one is not scaled + like "id" is, so it is recommended to either always use it + with a hash function (see "hash-key") or with explicitly + assigned ID values that are evenly distributed over the 32-bit + space. + addr The node keys will be derived from the server's address, when available, or else fall back on "id". diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index 69265cb06..bbc548081 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -249,7 +249,8 @@ struct pid_list { /* srv methods of computing chash keys */ enum srv_hash_key { - SRV_HASH_KEY_ID = 0, /* derived from server puid */ + 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_ADDR, /* derived from server address */ SRV_HASH_KEY_ADDR_PORT /* derived from server address and port */ }; diff --git a/src/lb_chash.c b/src/lb_chash.c index 362299d25..cf34370bf 100644 --- a/src/lb_chash.c +++ b/src/lb_chash.c @@ -121,6 +121,10 @@ static inline u32 chash_compute_server_key(struct server *s) } break; + case SRV_HASH_KEY_ID32: + key = full_hash(htonl(s->puid)); + break; + case SRV_HASH_KEY_ID: default: key = s->puid * SRV_EWGHT_RANGE; diff --git a/src/server.c b/src/server.c index 819e1c05a..4594e1a11 100644 --- a/src/server.c +++ b/src/server.c @@ -1015,13 +1015,16 @@ 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', 'addr', or 'addr-port' value", args[*cur_arg]); + memprintf(err, "'%s expects 'id', 'id32', 'addr', or 'addr-port' value", args[*cur_arg]); return ERR_ALERT | ERR_FATAL; } if (strcmp(args[*cur_arg + 1], "id") == 0) { newsrv->hash_key = SRV_HASH_KEY_ID; } + else if (strcmp(args[*cur_arg + 1], "id32") == 0) { + newsrv->hash_key = SRV_HASH_KEY_ID32; + } else if (strcmp(args[*cur_arg + 1], "addr") == 0) { newsrv->hash_key = SRV_HASH_KEY_ADDR; } @@ -1029,7 +1032,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', 'addr', or 'addr-port'", args[*cur_arg]); + memprintf(err, "'%s' has to be 'id', 'id32', 'addr', or 'addr-port'", args[*cur_arg]); return ERR_ALERT | ERR_FATAL; }