From cf095fdd9e45c0ee824b5c7634add7fe61d06ec8 Mon Sep 17 00:00:00 2001 From: phk Date: Tue, 11 Dec 2007 12:04:58 +0000 Subject: [PATCH] When an object is being fetched from the backend, other requests for it are parked not holding a worker thread, until the fetching session lowers the busy bit on the object. At that point we would release all the parked requests into the thread pool to be serviced, causing instant congestion and calls for road-pricing if the backend were a bit slow on an oft-requested object. Change the restart policy to be paced exponential: When we clear the busy bits, we unpark "rush_exponent" requests into the thread pool to start the show. Whenever the object is dereferenced, in practice whenever a request has been serviced, another "rush_exponent" worth of requests are unparked into the tread pool. Set the parameter to a conservative 3 until we know more about the behaviour in practice. If it is a big object and/or the clients are on slow lines, 3 may be an order of magnitude to small. Attempts to fix: #188 git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2294 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache_hash.c | 26 +++++++++++++++++-------- varnish-cache/bin/varnishd/heritage.h | 2 ++ varnish-cache/bin/varnishd/mgt_param.c | 19 ++++++++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index 1abc65b8..26e44b3f 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -244,11 +244,26 @@ HSH_Lookup(struct sess *sp) return (o); } +static void +hsh_rush(struct object *o) +{ + unsigned u; + struct sess *sp; + + for (u = 0; u < params->rush_exponent; u++) { + sp = VTAILQ_FIRST(&o->waitinglist); + if (sp == NULL) + return; + VTAILQ_REMOVE(&o->waitinglist, sp, list); + VSL(SLT_Debug, sp->id, "of waiting list"); + WRK_QueueSession(sp); + } +} + void HSH_Unbusy(struct object *o) { struct objhead *oh; - struct sess *sp; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); assert(o->busy); @@ -261,15 +276,9 @@ HSH_Unbusy(struct object *o) LOCK(&oh->mtx); } o->busy = 0; + hsh_rush(o); if (oh != NULL) UNLOCK(&oh->mtx); - while (1) { - sp = VTAILQ_FIRST(&o->waitinglist); - if (sp == NULL) - break; - VTAILQ_REMOVE(&o->waitinglist, sp, list); - WRK_QueueSession(sp); - } } void @@ -305,6 +314,7 @@ HSH_Deref(struct object *o) } assert(o->refcnt > 0); r = --o->refcnt; + hsh_rush(o); if (oh != NULL) { if (!r) VTAILQ_REMOVE(&oh->objects, o, list); diff --git a/varnish-cache/bin/varnishd/heritage.h b/varnish-cache/bin/varnishd/heritage.h index d84fbdc0..7e46615f 100644 --- a/varnish-cache/bin/varnishd/heritage.h +++ b/varnish-cache/bin/varnishd/heritage.h @@ -131,6 +131,8 @@ struct params { /* Maximum esi:include depth allowed */ unsigned max_esi_includes; + /* Rush exponent */ + unsigned rush_exponent; }; extern volatile struct params *params; diff --git a/varnish-cache/bin/varnishd/mgt_param.c b/varnish-cache/bin/varnishd/mgt_param.c index 15ee390d..3c293c6d 100644 --- a/varnish-cache/bin/varnishd/mgt_param.c +++ b/varnish-cache/bin/varnishd/mgt_param.c @@ -294,6 +294,17 @@ tweak_overflow_max(struct cli *cli, struct parspec *par, const char *arg) /*--------------------------------------------------------------------*/ +static void +tweak_rush_exponent(struct cli *cli, struct parspec *par, const char *arg) +{ + + (void)par; + tweak_generic_uint(cli, &master.rush_exponent, arg, + 2, UINT_MAX); +} + +/*--------------------------------------------------------------------*/ + static void tweak_http_workspace(struct cli *cli, struct parspec *par, const char *arg) { @@ -642,6 +653,14 @@ static struct parspec parspec[] = { "thread_pool_max parameter.", EXPERIMENTAL, "100", "%" }, + { "rush_exponent", tweak_rush_exponent, + "How many parked request we start for each completed " + "request on the object.\n" + "NB: Even with the implict delay of delivery, " + "this parameter controls an exponential increase in " + "number of worker threads. ", + EXPERIMENTAL, + "3", "requests per request" }, { "http_workspace", tweak_http_workspace, "Bytes of HTTP protocol workspace allocated. " "This space must be big enough for the entire HTTP protocol " -- 2.39.5