]> err.no Git - varnish/commitdiff
When an object is being fetched from the backend, other requests for it
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 11 Dec 2007 12:04:58 +0000 (12:04 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 11 Dec 2007 12:04:58 +0000 (12:04 +0000)
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
varnish-cache/bin/varnishd/heritage.h
varnish-cache/bin/varnishd/mgt_param.c

index 1abc65b8dd84d05214417e6a3d297331d05a2687..26e44b3f6b89df67db95c01473256a3570835c2a 100644 (file)
@@ -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);
index d84fbdc055ffe17585d31cb3c58a52010eebbca7..7e46615f9083132c5fb2785f5bde3d5ecc9f3975 100644 (file)
@@ -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;
index 15ee390dff0ffda0b5bccf036ec05c9a15d488e0..3c293c6ddaf35c6c9b34b9a5992568b3aa85a9ec 100644 (file)
@@ -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 "