mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-05 04:56:10 +02:00
[MEDIUM] hash: add support for an 'avalanche' hash-type
When the number of servers is a multiple of the size of the input set, map-based hash can be inefficient. This typically happens with 64 servers when doing URI hashing. The "avalanche" hash-type applies an avalanche hash before performing a map lookup in order to smooth the distribution. The result is slightly less smooth than the map for small numbers of servers, but still better than the consistent hashing.
This commit is contained in:
parent
4c14eaa0d4
commit
798a39cdc9
@ -2235,6 +2235,15 @@ hash-type <method>
|
||||
to a farm, most connections will be redistributed to different
|
||||
servers. This can be inconvenient with caches for instance.
|
||||
|
||||
avalanche this mechanism uses the default map-based hashing described
|
||||
above but applies a full avalanche hash before performing the
|
||||
mapping. The result is a slightly less smooth hash for most
|
||||
situations, but the hash becomes better than pure map-based
|
||||
hashes when the number of servers is a multiple of the size of
|
||||
the input set. When using URI hash with a number of servers
|
||||
multiple of 64, it's desirable to change the hash type to
|
||||
this value.
|
||||
|
||||
consistent the hash table is a tree filled with many occurrences of each
|
||||
server. The hash key is looked up in the tree and the closest
|
||||
server is chosen. This hash is dynamic, it supports changing
|
||||
|
||||
@ -94,7 +94,8 @@
|
||||
/* hash types */
|
||||
#define BE_LB_HASH_MAP 0x000000 /* map-based hash (default) */
|
||||
#define BE_LB_HASH_CONS 0x100000 /* consistent hashbit to indicate a dynamic algorithm */
|
||||
#define BE_LB_HASH_TYPE 0x100000 /* get/clear hash types */
|
||||
#define BE_LB_HASH_AVAL 0x200000 /* run an avalanche hash before a map */
|
||||
#define BE_LB_HASH_TYPE 0x300000 /* get/clear hash types */
|
||||
|
||||
/* various constants */
|
||||
|
||||
|
||||
@ -118,6 +118,8 @@ struct server *get_server_sh(struct proxy *px, const char *addr, int len)
|
||||
h ^= ntohl(*(unsigned int *)(&addr[l]));
|
||||
l += sizeof (int);
|
||||
}
|
||||
if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP)
|
||||
h = full_hash(h);
|
||||
hash_done:
|
||||
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
|
||||
return chash_get_server_hash(px, h);
|
||||
@ -165,6 +167,8 @@ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
|
||||
|
||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||
}
|
||||
if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP)
|
||||
hash = full_hash(hash);
|
||||
hash_done:
|
||||
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
|
||||
return chash_get_server_hash(px, hash);
|
||||
@ -217,6 +221,8 @@ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
|
||||
uri_len--;
|
||||
p++;
|
||||
}
|
||||
if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP)
|
||||
hash = full_hash(hash);
|
||||
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
|
||||
return chash_get_server_hash(px, hash);
|
||||
else
|
||||
@ -285,6 +291,8 @@ struct server *get_server_ph_post(struct session *s)
|
||||
p++;
|
||||
/* should we break if vlen exceeds limit? */
|
||||
}
|
||||
if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP)
|
||||
hash = full_hash(hash);
|
||||
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
|
||||
return chash_get_server_hash(px, hash);
|
||||
else
|
||||
@ -374,6 +382,8 @@ struct server *get_server_hh(struct session *s)
|
||||
p--;
|
||||
}
|
||||
}
|
||||
if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP)
|
||||
hash = full_hash(hash);
|
||||
hash_done:
|
||||
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
|
||||
return chash_get_server_hash(px, hash);
|
||||
@ -419,6 +429,8 @@ struct server *get_server_rch(struct session *s)
|
||||
len--;
|
||||
p++;
|
||||
}
|
||||
if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP)
|
||||
hash = full_hash(hash);
|
||||
hash_done:
|
||||
if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
|
||||
return chash_get_server_hash(px, hash);
|
||||
|
||||
@ -3788,8 +3788,12 @@ stats_error_parsing:
|
||||
curproxy->lbprm.algo &= ~BE_LB_HASH_TYPE;
|
||||
curproxy->lbprm.algo |= BE_LB_HASH_MAP;
|
||||
}
|
||||
else if (strcmp(args[1], "avalanche") == 0) { /* use full hash before map-based hashing */
|
||||
curproxy->lbprm.algo &= ~BE_LB_HASH_TYPE;
|
||||
curproxy->lbprm.algo |= BE_LB_HASH_AVAL;
|
||||
}
|
||||
else {
|
||||
Alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
|
||||
Alert("parsing [%s:%d] : '%s' only supports 'avalanche', 'consistent' and 'map-based'.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -271,8 +271,6 @@ struct server *chash_get_server_hash(struct proxy *p, unsigned int hash)
|
||||
else
|
||||
return NULL;
|
||||
|
||||
hash = full_hash(hash);
|
||||
|
||||
/* find the node after and the node before */
|
||||
next = eb32_lookup_ge(root, hash);
|
||||
if (!next)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user