mirror of
https://github.com/haproxy/haproxy.git
synced 2026-06-10 17:32:03 -04:00
MINOR: server: support hash-key id32 for a cleaner distribution
The "id" hash-key scales the ID by a factor of 16 that tries to leave room between the nodes on the 32-bit space to permit smooth weight variations (e.g. during slowstart). However this does not deal well with overlaps between server IDs. For example, assigning IDs that are only multiples of 256 million to 16 servers yields traffic only on one since in practice they all have the same 28 lower bits. The new "id32" hash key bridges this gap by using the full 32-bit ID of the server as the key. On the other hand, the user must be careful not to switch the hash function to "none" when using incremental IDs because in this case they might be very poorly distributed. But this can be convenient for automated provisionning systems which assign IDs themselves, as the full 32 bits are used now.
This commit is contained in:
parent
cb5d98c495
commit
a59e6e5efd
4 changed files with 20 additions and 3 deletions
|
|
@ -18850,6 +18850,15 @@ hash-key <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".
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue