From f3bd8a9fabf14916198a0dbdc587b6b69bb9a203 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Tue, 16 Jun 2015 15:38:12 +0900 Subject: [PATCH] Add spare2 cheaper algorithm for larger workload --- core/init.c | 1 + core/master_utils.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ core/uwsgi.c | 2 ++ uwsgi.h | 2 ++ 4 files changed, 73 insertions(+) diff --git a/core/init.c b/core/init.c index 4c24dadf..757b2def 100644 --- a/core/init.c +++ b/core/init.c @@ -111,6 +111,7 @@ void uwsgi_init_default() { uwsgi.listen_queue = 100; uwsgi.cheaper_overload = 3; + uwsgi.cheaper_idle = 10; uwsgi.log_master_bufsize = 8192; diff --git a/core/master_utils.c b/core/master_utils.c index 99147f55..5377ebad 100644 --- a/core/master_utils.c +++ b/core/master_utils.c @@ -333,6 +333,72 @@ healthy: } +/* + -- Cheaper, spare2 algorithm, for large workload -- + + This algorithm is very similar to spare, but more suited for higher workload. + + This algorithm increase workers *before* overloaded, and decrease workers slowly. + + This algorithm uses these options: chaper, cheaper-initial, cheaper-step and cheaper-idle. + + * When number of idle workers is smaller than cheaper count, increase + min(cheaper-step, cheaper - idle workers) workers. + * When number of idle workers is larger than cheaper count, increase idle_count. + * When idle_count >= cheaper-idle, decrease worker. +*/ +int uwsgi_cheaper_algo_spare2(int can_spawn) { + static int idle_count = 0; + int i, idle_workers, busy_workers, cheaped_workers; + + // count the number of idle and busy workers + idle_workers = busy_workers = 0; + for (i = 1; i <= uwsgi.numproc; i++) { + if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) { + if (uwsgi_worker_is_busy(i) == 1) { + busy_workers++; + } else { + idle_workers++; + } + } + } + cheaped_workers = uwsgi.numproc - (idle_workers + busy_workers); + +#ifdef UWSGI_DEBUG + uwsgi_log("cheaper-spare2: idle=%d, busy=%d, cheaped=%d, idle_count=%d\n", + idle_workers, busy_workers, cheaped_workers, idle_count); +#endif + + // should we increase workers? + if (idle_workers < uwsgi.cheaper_count) { + int spawn; + idle_count = 0; + + if (!can_spawn) + return 0; + + spawn = uwsgi.cheaper_count - idle_workers; + if (spawn > cheaped_workers) + spawn = cheaped_workers; + if (spawn > uwsgi.cheaper_step) + spawn = uwsgi.cheaper_step; + return spawn; + } + + if (idle_workers == uwsgi.cheaper_count) { + idle_count = 0; + return 0; + } + + // decrease workers + idle_count++; + if (idle_count < uwsgi.cheaper_idle) + return 0; + + idle_count = 0; + return -1; +} + /* @@ -1869,3 +1935,5 @@ void uwsgi_dump_worker(int wid, char *msg) { } uwsgi_log_verbose("%s !!! end of worker %d status !!!\n",msg, wid); } + +/* vim: set ts=8 sts=0 sw=0 noexpandtab : */ diff --git a/core/uwsgi.c b/core/uwsgi.c index 92937ce6..080536fe 100755 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -790,6 +790,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"cheaper-algo", required_argument, 0, "choose to algorithm used for adaptive process spawning", uwsgi_opt_set_str, &uwsgi.requested_cheaper_algo, UWSGI_OPT_MASTER}, {"cheaper-step", required_argument, 0, "number of additional processes to spawn at each overload", uwsgi_opt_set_int, &uwsgi.cheaper_step, UWSGI_OPT_MASTER | UWSGI_OPT_CHEAPER}, {"cheaper-overload", required_argument, 0, "increase workers after specified overload", uwsgi_opt_set_64bit, &uwsgi.cheaper_overload, UWSGI_OPT_MASTER | UWSGI_OPT_CHEAPER}, + {"cheaper-idle", required_argument, 0, "decrease workers after specified idle (algo: spare2) (default: 10)", uwsgi_opt_set_int, &uwsgi.cheaper_idle, UWSGI_OPT_MASTER | UWSGI_OPT_CHEAPER}, {"cheaper-algo-list", no_argument, 0, "list enabled cheapers algorithms", uwsgi_opt_true, &uwsgi.cheaper_algo_list, 0}, {"cheaper-algos-list", no_argument, 0, "list enabled cheapers algorithms", uwsgi_opt_true, &uwsgi.cheaper_algo_list, 0}, {"cheaper-list", no_argument, 0, "list enabled cheapers algorithms", uwsgi_opt_true, &uwsgi.cheaper_algo_list, 0}, @@ -2361,6 +2362,7 @@ configure: // setup cheaper algos uwsgi_register_cheaper_algo("spare", uwsgi_cheaper_algo_spare); + uwsgi_register_cheaper_algo("spare2", uwsgi_cheaper_algo_spare2); uwsgi_register_cheaper_algo("backlog", uwsgi_cheaper_algo_backlog); uwsgi_register_cheaper_algo("manual", uwsgi_cheaper_algo_manual); diff --git a/uwsgi.h b/uwsgi.h index a6f0129d..feb5e926 100755 --- a/uwsgi.h +++ b/uwsgi.h @@ -2802,6 +2802,7 @@ struct uwsgi_server { int die_on_no_workers; int spooler_cheap; + int cheaper_idle; }; struct uwsgi_rpc { @@ -3953,6 +3954,7 @@ time_t uwsgi_now(void); int uwsgi_calc_cheaper(void); int uwsgi_cheaper_algo_spare(int); +int uwsgi_cheaper_algo_spare2(int); int uwsgi_cheaper_algo_backlog(int); int uwsgi_cheaper_algo_backlog2(int); int uwsgi_cheaper_algo_manual(int);