r4460 - trunk/varnish-cache/bin/varnishd
phk at projects.linpro.no
phk at projects.linpro.no
Thu Jan 14 14:35:56 CET 2010
Author: phk
Date: 2010-01-14 14:35:56 +0100 (Thu, 14 Jan 2010)
New Revision: 4460
Modified:
trunk/varnish-cache/bin/varnishd/cache_backend.h
trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c
trunk/varnish-cache/bin/varnishd/cache_dir_random.c
Log:
Experimental "client" director, which chooses backend based on
client-ip.
This does _not_ take X-Forwarded-For: into account.
Feedback welcome.
Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-01-14 11:59:57 UTC (rev 4459)
+++ trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-01-14 13:35:56 UTC (rev 4460)
@@ -160,3 +160,4 @@
dir_init_f VRT_init_dir_hash;
dir_init_f VRT_init_dir_random;
dir_init_f VRT_init_dir_round_robin;
+dir_init_f VRT_init_dir_client;
Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-01-14 11:59:57 UTC (rev 4459)
+++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-01-14 13:35:56 UTC (rev 4460)
@@ -275,6 +275,8 @@
VRT_init_dir_random(cli, dir, idx, priv);
else if (!strcmp(name, "round-robin"))
VRT_init_dir_round_robin(cli, dir, idx, priv);
+ else if (!strcmp(name, "client"))
+ VRT_init_dir_client(cli, dir, idx, priv);
else
INCOMPL();
}
Modified: trunk/varnish-cache/bin/varnishd/cache_dir_random.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-01-14 11:59:57 UTC (rev 4459)
+++ trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-01-14 13:35:56 UTC (rev 4460)
@@ -57,6 +57,7 @@
#include "cache.h"
#include "cache_backend.h"
#include "vrt.h"
+#include "vsha256.h"
/*--------------------------------------------------------------------*/
@@ -65,12 +66,14 @@
double weight;
};
+enum crit_e {c_random, c_hash, c_client};
+
struct vdi_random {
unsigned magic;
#define VDI_RANDOM_MAGIC 0x3771ae23
struct director dir;
- unsigned use_hash;
+ enum crit_e criteria;
unsigned retries;
double tot_weight;
struct vdi_random_host *hosts;
@@ -86,22 +89,47 @@
unsigned u;
struct vbe_conn *vbe;
struct director *d2;
+ struct SHA256Context ctx;
+ unsigned char sign[SHA256_LEN], *hp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(vs, d->priv, VDI_RANDOM_MAGIC);
+ if (vs->criteria == c_client) {
+ /*
+ * Hash the client IP# ascii representation, rather than
+ * rely on the raw IP# being a good hash distributor, since
+ * experience shows this not to be the case.
+ * We do not hash the port number, to make everybody behind
+ * a given NAT gateway fetch from the same backend.
+ */
+ SHA256_Init(&ctx);
+ AN(sp->addr);
+ SHA256_Update(&ctx, sp->addr, strlen(sp->addr));
+ SHA256_Final(sign, &ctx);
+ hp = sign;
+ }
+ if (vs->criteria == c_hash) {
+ /*
+ * Reuse the hash-string, the objective here is to fetch the
+ * same object on the same backend all the time
+ */
+ hp = sp->digest;
+ }
+
/*
* If we are hashing, first try to hit our "canonical backend"
* If that fails, we fall through, and select a weighted backend
- * amongst the good set.
+ * amongst the healthy set.
*/
- if (vs->use_hash) {
- u = sp->digest[3] << 24;
- u |= sp->digest[2] << 16;
- u |= sp->digest[1] << 8;
- u |= sp->digest[0] << 0;
+ if (vs->criteria != c_random) {
+ u = hp[3] << 24;
+ u |= hp[2] << 16;
+ u |= hp[1] << 8;
+ u |= hp[0] << 0;
r = u / 4294967296.0;
+ assert(r >= 0.0 && r < 1.0);
r *= vs->tot_weight;
s1 = 0.0;
for (i = 0; i < vs->nhosts; i++) {
@@ -119,7 +147,6 @@
}
for (k = 0; k < vs->retries; ) {
-
/* Sum up the weights of healty backends */
s1 = 0.0;
for (i = 0; i < vs->nhosts; i++) {
@@ -132,11 +159,7 @@
if (s1 == 0.0)
return (NULL);
- if (vs->use_hash) {
- u = sp->digest[3] << 24;
- u |= sp->digest[2] << 16;
- u |= sp->digest[1] << 8;
- u |= sp->digest[0] << 0;
+ if (vs->criteria != c_random) {
r = u / 4294967296.0;
} else {
/* Pick a random threshold in that interval */
@@ -197,7 +220,7 @@
static void
vrt_init(struct cli *cli, struct director **bp, int idx,
- const void *priv, int use_hash)
+ const void *priv, enum crit_e criteria)
{
const struct vrt_dir_random *t;
struct vdi_random *vs;
@@ -222,7 +245,7 @@
vs->dir.fini = vdi_random_fini;
vs->dir.healthy = vdi_random_healthy;
- vs->use_hash = use_hash;
+ vs->criteria = criteria;
vs->retries = t->retries;
if (vs->retries == 0)
vs->retries = t->nmember;
@@ -244,12 +267,19 @@
VRT_init_dir_random(struct cli *cli, struct director **bp, int idx,
const void *priv)
{
- vrt_init(cli, bp, idx, priv, 0);
+ vrt_init(cli, bp, idx, priv, c_random);
}
void
VRT_init_dir_hash(struct cli *cli, struct director **bp, int idx,
const void *priv)
{
- vrt_init(cli, bp, idx, priv, 1);
+ vrt_init(cli, bp, idx, priv, c_hash);
}
+
+void
+VRT_init_dir_client(struct cli *cli, struct director **bp, int idx,
+ const void *priv)
+{
+ vrt_init(cli, bp, idx, priv, c_client);
+}
More information about the varnish-commit
mailing list