From: Jim Jagielski Date: Thu, 16 Dec 2004 14:09:30 +0000 (+0000) Subject: simplify the BalancerMember load factor weighting. Instead of X-Git-Tag: 2.1.3~237 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79419db65ac4d38b39d4e159e7b8b43df182b2d0;p=thirdparty%2Fapache%2Fhttpd.git simplify the BalancerMember load factor weighting. Instead of being percentages (and adjusting when the number don't add up), loadfactors/lbfactors are now normalized values, so values like: worker a b c lbfactor 1 1 2 work as expected (ie: a gets 25%, b gets 25% and c gets 50%). So we could also have the above as: worker a b c lbfactor 25 25 50 or even worker a b c lbfactor 15 15 30 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@122551 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index b6e946cf191..c68c80fc5e3 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.1.3 [Remove entries to the current 2.0 section below, when backported] + *) Significantly simplify the load balancer scheduling algorithm + for the proxy BalancerMember weighting. loadfactors (lbfactors) + are now normalized with respect to each other. [Jim Jagielski] + *) mod_dumpio: Added to the available module suite. Placed in the (new) debug module subdirectory. mod_bucketeer moved to that directory as well. [Jim Jagielski] diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 4ce39f5cb97..84633cc7157 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -91,8 +91,8 @@ static const char *set_worker_param(apr_pool_t *p, int ival; if (!strcasecmp(key, "loadfactor")) { - /* Worker load factor. Used with BalancerMamber - * It is a number between 1 and 100 in percents. + /* Normalized load factor. Used with BalancerMamber, + * it is a number between 1 and 100. */ worker->lbfactor = atoi(val); if (worker->lbfactor < 1 || worker->lbfactor > 100) diff --git a/modules/proxy/proxy_balancer.c b/modules/proxy/proxy_balancer.c index 6138911b9f5..f0ea37d5c94 100644 --- a/modules/proxy/proxy_balancer.c +++ b/modules/proxy/proxy_balancer.c @@ -27,7 +27,6 @@ static int init_balancer_members(proxy_server_conf *conf, server_rec *s, proxy_balancer *balancer) { int i; - int median, ffactor = 0; proxy_worker *workers; workers = (proxy_worker *)balancer->workers->elts; @@ -39,41 +38,10 @@ static int init_balancer_members(proxy_server_conf *conf, server_rec *s, } workers = (proxy_worker *)balancer->workers->elts; - /* Recalculate lbfactors */ for (i = 0; i < balancer->workers->nelts; i++) { /* Set to the original configuration */ - workers[i].s->lbfactor = workers[i].lbfactor; - ffactor += workers[i].s->lbfactor; - } - if (ffactor < 100) { - int z = 0; - for (i = 0; i < balancer->workers->nelts; i++) { - if (workers[i].s->lbfactor == 0) - ++z; - } - if (z) { - median = (100 - ffactor) / z; - for (i = 0; i < balancer->workers->nelts; i++) { - if (workers[i].s->lbfactor == 0) - workers[i].s->lbfactor = median; - } - } - else { - median = (100 - ffactor) / balancer->workers->nelts; - for (i = 0; i < balancer->workers->nelts; i++) - workers[i].s->lbfactor += median; - } - } - else if (ffactor > 100) { - median = (ffactor - 100) / balancer->workers->nelts; - for (i = 0; i < balancer->workers->nelts; i++) { - if (workers[i].s->lbfactor > median) - workers[i].s->lbfactor -= median; - } - } - for (i = 0; i < balancer->workers->nelts; i++) { - /* Update the status entires */ - workers[i].s->lbstatus = workers[i].s->lbfactor; + workers[i].s->lbstatus = workers[i].s->lbfactor = + (workers[i].lbfactor ? workers[i].lbfactor : 1); } return 0; } @@ -196,7 +164,7 @@ static proxy_worker *find_session_route(proxy_balancer *balancer, * The idea behind this scheduler is the following: * * lbfactor is "how much we expect this worker to work", or "the worker's - * work quota". + * normalized work quota". * * lbstatus is "how urgent this worker has to work to fulfill its quota * of work". @@ -214,37 +182,29 @@ static proxy_worker *find_session_route(proxy_balancer *balancer, * * worker a b c d * lbfactor 25 25 25 25 - * lbstatus 0 0 0 0 * * And b gets disabled, the following schedule is produced: * - * lbstatus -50 0 25 25 - * lbstatus -25 0 -25 50 - * lbstatus 0 0 0 0 - * (repeat) + * a c d a c d a c d ... + * + * Note that the above lbfactor setting is the *exact* same as: * - * That is it schedules: a c d a c d a c d ... + * worker a b c d + * lbfactor 1 1 1 1 + * + * Asymmetric configurations work as one would expect. For + * example: * - * The following asymmetric configuration works as one would expect: + * worker a b c d + * lbfactor 1 1 1 2 * - * worker a b - * lbfactor 70 30 + * would have a, b and c all handling about the same + * amount of load with d handling twice what a or b + * or c handles individually. So we could see: * - * lbstatus -30 30 - * lbstatus 40 -40 - * lbstatus 10 -10 - * lbstatus -20 20 - * lbstatus -50 50 - * lbstatus 20 -20 - * lbstatus -10 10 - * lbstatus -40 40 - * lbstatus 30 -30 - * lbasatus 0 0 - * (repeat) + * b a d c d a c d b d ... * - * That is after 10 schedules, the schedule repeats and 7 a are selected - * with 3 b interspersed. -*/ + */ static proxy_worker *find_best_worker(proxy_balancer *balancer, request_rec *r) { @@ -461,51 +421,23 @@ static int proxy_balancer_post_request(proxy_worker *worker, return OK; } -static void recalc_factors(proxy_balancer *balancer, - proxy_worker *fixed) +static void recalc_factors(proxy_balancer *balancer) { int i; - int median, ffactor = 0; proxy_worker *workers; /* Recalculate lbfactors */ workers = (proxy_worker *)balancer->workers->elts; /* Special case if there is only one worker it's - * load factor will always be 100 + * load factor will always be 1 */ if (balancer->workers->nelts == 1) { - workers->s->lbstatus = workers->s->lbfactor = 100; + workers->s->lbstatus = workers->s->lbfactor = 1; return; } for (i = 0; i < balancer->workers->nelts; i++) { - if (workers[i].s->lbfactor > 100) - workers[i].s->lbfactor = 100; - ffactor += workers[i].s->lbfactor; - } - if (ffactor < 100) { - median = (100 - ffactor) / (balancer->workers->nelts - 1); - for (i = 0; i < balancer->workers->nelts; i++) { - if (&(workers[i]) != fixed) - workers[i].s->lbfactor += median; - } - } - else if (fixed->s->lbfactor < 100) { - median = (ffactor - 100) / (balancer->workers->nelts - 1); - for (i = 0; i < balancer->workers->nelts; i++) { - if (workers[i].s->lbfactor > median && - &(workers[i]) != fixed) - workers[i].s->lbfactor -= median; - } - } - else { - median = (ffactor - 100) / balancer->workers->nelts; - for (i = 0; i < balancer->workers->nelts; i++) { - workers[i].s->lbfactor -= median; - } - } - for (i = 0; i < balancer->workers->nelts; i++) { - /* Update the status entires */ + /* Update the status entries */ workers[i].s->lbstatus = workers[i].s->lbfactor; } } @@ -595,10 +527,10 @@ static int balancer_handler(request_rec *r) const char *val; if ((val = apr_table_get(params, "lf"))) { int ival = atoi(val); - if (ival > 1) { + if (ival >= 1 && ival <= 100) { wsel->s->lbfactor = ival; if (bsel) - recalc_factors(bsel, wsel); + recalc_factors(bsel); } } if ((val = apr_table_get(params, "wr"))) {