BUG/MEDIUM: server: set the macro for server's max weight SRV_UWGHT_MAX to SRV_UWGHT_RANGE

The max weight of server is 256 now, but SRV_UWGHT_MAX is still 255. As a result,
FWRR will not work well when server's weight is 256. The description is as below:

There are some macros related to server's weight in include/types/server.h:
    #define SRV_UWGHT_RANGE 256
    #define SRV_UWGHT_MAX   (SRV_UWGHT_RANGE - 1)
    #define SRV_EWGHT_MAX   (SRV_UWGHT_MAX   * BE_WEIGHT_SCALE)

Since weight of server can be reach to 256 and BE_WEIGHT_SCALE equals to 16,
the max eweight of server should be 256*16 = 4096, it will exceed SRV_EWGHT_MAX
which equals to SRV_UWGHT_MAX*BE_WEIGHT_SCALE = 255*16 = 4080. When a server
with weight 256 is insterted into FWRR tree during initialization, the key value
of this server should be SRV_EWGHT_MAX - s->eweight = 4080 - 4096 = -16 which
is closed to UINT_MAX in unsigned type, so the server with highest weight will
be not elected as the first server to process request.

In addition, it is a better choice to compare with SRV_UWGHT_MAX than a magic
number 256 while doing check for the weight. The max number of servers for
round-robin algorithm is also updated.

Signed-off-by: Godbach <nylzhaowei@gmail.com>
This commit is contained in:
Godbach 2013-07-22 07:44:53 +08:00 committed by Willy Tarreau
parent 506d050600
commit a34bdc0ea4
5 changed files with 8 additions and 8 deletions

View File

@ -1400,7 +1400,7 @@ balance url_param <param> [check_post [<max_wait>]]
processing time remains equally distributed. This algorithm processing time remains equally distributed. This algorithm
is dynamic, which means that server weights may be adjusted is dynamic, which means that server weights may be adjusted
on the fly for slow starts for instance. It is limited by on the fly for slow starts for instance. It is limited by
design to 4128 active servers per backend. Note that in some design to 4095 active servers per backend. Note that in some
large farms, when a server becomes up after having been down large farms, when a server becomes up after having been down
for a very short time, it may sometimes take a few hundreds for a very short time, it may sometimes take a few hundreds
requests for it to be re-integrated into the farm and start requests for it to be re-integrated into the farm and start

View File

@ -114,8 +114,8 @@
* weight modulation even with small weights (eg: 1). It should not be too high * weight modulation even with small weights (eg: 1). It should not be too high
* though because it limits the number of servers in FWRR mode in order to * though because it limits the number of servers in FWRR mode in order to
* prevent any integer overflow. The max number of servers per backend is * prevent any integer overflow. The max number of servers per backend is
* limited to about 2^32/255^2/scale ~= 66051/scale. A scale of 16 looks like * limited to about (2^32-1)/256^2/scale ~= 65535.9999/scale. A scale of 16
* a good value, as it allows more than 4000 servers per backend while leaving * looks like a good value, as it allows 4095 servers per backend while leaving
* modulation steps of about 6% for servers with the lowest weight (1). * modulation steps of about 6% for servers with the lowest weight (1).
*/ */
#define BE_WEIGHT_SCALE 16 #define BE_WEIGHT_SCALE 16

View File

@ -72,7 +72,7 @@
/* various constants */ /* various constants */
#define SRV_UWGHT_RANGE 256 #define SRV_UWGHT_RANGE 256
#define SRV_UWGHT_MAX (SRV_UWGHT_RANGE - 1) #define SRV_UWGHT_MAX (SRV_UWGHT_RANGE)
#define SRV_EWGHT_RANGE (SRV_UWGHT_RANGE * BE_WEIGHT_SCALE) #define SRV_EWGHT_RANGE (SRV_UWGHT_RANGE * BE_WEIGHT_SCALE)
#define SRV_EWGHT_MAX (SRV_UWGHT_MAX * BE_WEIGHT_SCALE) #define SRV_EWGHT_MAX (SRV_UWGHT_MAX * BE_WEIGHT_SCALE)

View File

@ -4392,9 +4392,9 @@ stats_error_parsing:
else if (!strcmp(args[cur_arg], "weight")) { else if (!strcmp(args[cur_arg], "weight")) {
int w; int w;
w = atol(args[cur_arg + 1]); w = atol(args[cur_arg + 1]);
if (w < 0 || w > 256) { if (w < 0 || w > SRV_UWGHT_MAX) {
Alert("parsing [%s:%d] : weight of server %s is not within 0 and 256 (%d).\n", Alert("parsing [%s:%d] : weight of server %s is not within 0 and %d (%d).\n",
file, linenum, newsrv->id, w); file, linenum, newsrv->id, SRV_UWGHT_MAX, w);
err_code |= ERR_ALERT | ERR_FATAL; err_code |= ERR_ALERT | ERR_FATAL;
goto out; goto out;
} }

View File

@ -343,7 +343,7 @@ static void fwrr_queue_srv(struct server *s)
* lower the scale, the rougher the weights modulation, and the * lower the scale, the rougher the weights modulation, and the
* higher the scale, the lower the number of servers without * higher the scale, the lower the number of servers without
* overflow. With this formula, the result is always positive, * overflow. With this formula, the result is always positive,
* so we can use eb3é_insert(). * so we can use eb32_insert().
*/ */
s->lb_node.key = SRV_UWGHT_RANGE * s->npos + s->lb_node.key = SRV_UWGHT_RANGE * s->npos +
(unsigned)(SRV_EWGHT_MAX + s->rweight - s->eweight) / BE_WEIGHT_SCALE; (unsigned)(SRV_EWGHT_MAX + s->rweight - s->eweight) / BE_WEIGHT_SCALE;