Skip to content

Commit

Permalink
The needed glue and function renames to integrate userhash and soucehash
Browse files Browse the repository at this point in the history
  • Loading branch information
hno committed Jul 11, 2008
1 parent 76ea7c1 commit f7e1d9c
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 91 deletions.
12 changes: 12 additions & 0 deletions src/cache_cf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,18 @@ parse_peer(peer ** head)

p->options.carp = 1;

} else if (!strcasecmp(token, "userhash")) {
if (p->type != PEER_PARENT)
fatalf("parse_peer: non-parent userhash peer %s/%d\n", p->host, p->http_port);

p->options.userhash = 1;

} else if (!strcasecmp(token, "sourcehash")) {
if (p->type != PEER_PARENT)
fatalf("parse_peer: non-parent sourcehash peer %s/%d\n", p->host, p->http_port);

p->options.sourcehash = 1;

#if DELAY_POOLS

} else if (!strcasecmp(token, "no-delay")) {
Expand Down
8 changes: 8 additions & 0 deletions src/cf.data.pre
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,8 @@ DOC_START
round-robin
weighted-round-robin
carp
userhash
sourcehash
multicast-responder
closest-only
no-digest
Expand Down Expand Up @@ -1645,6 +1647,12 @@ DOC_START
distributed among the parents based on the CARP load
balancing hash function based on their weight.

use 'userhash' to load-balance amongst a set of parents
based on the client proxy_auth or ident username.

use 'sourcehash' to load-balance amongst a set of parents
based on the client source ip.

'multicast-responder' indicates the named peer
is a member of a multicast group. ICP queries will
not be sent directly to the peer, but ICP replies
Expand Down
4 changes: 4 additions & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,8 @@ serverConnectionsOpen(void)
peerSelectInit();

carpInit();
peerUserHashInit();
peerSourceHashInit();
}

void
Expand Down Expand Up @@ -969,6 +971,8 @@ mainInitialize(void)
asnRegisterWithCacheManager(manager);
authenticateRegisterWithCacheManager(&Config.authConfiguration, manager);
carpRegisterWithCacheManager(manager);
peerUserHashRegisterWithCacheManager(manager);
peerSourceHashRegisterWithCacheManager(manager);
cbdataRegisterWithCacheManager(manager);
/* These use separate calls so that the comm loops can eventually
* coexist.
Expand Down
9 changes: 9 additions & 0 deletions src/neighbors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,15 @@ dump_peer_options(StoreEntry * sentry, peer * p)
if (p->options.roundrobin)
storeAppendPrintf(sentry, " round-robin");

if (p->options.carp)
storeAppendPrintf(sentry, " carp");

if (p->options.userhash)
storeAppendPrintf(sentry, " userhash");

if (p->options.userhash)
storeAppendPrintf(sentry, " sourcehash");

if (p->options.weighted_roundrobin)
storeAppendPrintf(sentry, " weighted-round-robin");

Expand Down
4 changes: 4 additions & 0 deletions src/peer_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,10 @@ peerGetSomeParent(ps_state * ps)

if ((p = getDefaultParent(request))) {
code = DEFAULT_PARENT;
} else if ((p = peerUserHashSelectParent(request))) {
code = USERHASH_PARENT;
} else if ((p = peerSourceHashSelectParent(request))) {
code = SOURCEHASH_PARENT;
} else if ((p = carpSelectParent(request))) {
code = CARP;
} else if ((p = getRoundRobinParent(request))) {
Expand Down
90 changes: 45 additions & 45 deletions src/peer_sourcehash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

static int n_carp_peers = 0;
static peer **carp_peers = NULL;
static OBJH carpCachemgr;
static int n_sourcehash_peers = 0;
static peer **sourcehash_peers = NULL;
static OBJH peerSourceHashCachemgr;

static int
peerSortWeight(const void *a, const void *b)
Expand All @@ -53,7 +53,7 @@ peerSortWeight(const void *a, const void *b)
}

void
carpInit(void)
peerSourceHashInit(void)
{
int W = 0;
int K;
Expand All @@ -64,63 +64,63 @@ carpInit(void)
char *t;
/* Clean up */

for (k = 0; k < n_carp_peers; k++) {
cbdataReferenceDone(carp_peers[k]);
for (k = 0; k < n_sourcehash_peers; k++) {
cbdataReferenceDone(sourcehash_peers[k]);
}

safe_free(carp_peers);
n_carp_peers = 0;
safe_free(sourcehash_peers);
n_sourcehash_peers = 0;
/* find out which peers we have */

for (p = Config.peers; p; p = p->next) {
if (!p->options.carp)
if (!p->options.sourcehash)
continue;

assert(p->type == PEER_PARENT);

if (p->weight == 0)
continue;

n_carp_peers++;
n_sourcehash_peers++;

W += p->weight;
}

if (n_carp_peers == 0)
if (n_sourcehash_peers == 0)
return;

carp_peers = (peer **)xcalloc(n_carp_peers, sizeof(*carp_peers));
sourcehash_peers = (peer **)xcalloc(n_sourcehash_peers, sizeof(*sourcehash_peers));

/* Build a list of the found peers and calculate hashes and load factors */
for (P = carp_peers, p = Config.peers; p; p = p->next) {
if (!p->options.carp)
for (P = sourcehash_peers, p = Config.peers; p; p = p->next) {
if (!p->options.sourcehash)
continue;

if (p->weight == 0)
continue;

/* calculate this peers hash */
p->carp.hash = 0;
p->sourcehash.hash = 0;

for (t = p->name; *t != 0; t++)
p->carp.hash += ROTATE_LEFT(p->carp.hash, 19) + (unsigned int) *t;
p->sourcehash.hash += ROTATE_LEFT(p->sourcehash.hash, 19) + (unsigned int) *t;

p->carp.hash += p->carp.hash * 0x62531965;
p->sourcehash.hash += p->sourcehash.hash * 0x62531965;

p->carp.hash = ROTATE_LEFT(p->carp.hash, 21);
p->sourcehash.hash = ROTATE_LEFT(p->sourcehash.hash, 21);

/* and load factor */
p->carp.load_factor = ((double) p->weight) / (double) W;
p->sourcehash.load_factor = ((double) p->weight) / (double) W;

if (floor(p->carp.load_factor * 1000.0) == 0.0)
p->carp.load_factor = 0.0;
if (floor(p->sourcehash.load_factor * 1000.0) == 0.0)
p->sourcehash.load_factor = 0.0;

/* add it to our list of peers */
*P++ = cbdataReference(p);
}

/* Sort our list on weight */
qsort(carp_peers, n_carp_peers, sizeof(*carp_peers), peerSortWeight);
qsort(sourcehash_peers, n_sourcehash_peers, sizeof(*sourcehash_peers), peerSortWeight);

/* Calculate the load factor multipliers X_k
*
Expand All @@ -130,7 +130,7 @@ carpInit(void)
* X_k = pow (X_k, {1/(K-k+1)})
* simplified to have X_1 part of the loop
*/
K = n_carp_peers;
K = n_sourcehash_peers;

P_last = 0.0; /* Empty P_0 */

Expand All @@ -140,24 +140,24 @@ carpInit(void)

for (k = 1; k <= K; k++) {
double Kk1 = (double) (K - k + 1);
p = carp_peers[k - 1];
p->carp.load_multiplier = (Kk1 * (p->carp.load_factor - P_last)) / Xn;
p->carp.load_multiplier += pow(X_last, Kk1);
p->carp.load_multiplier = pow(p->carp.load_multiplier, 1.0 / Kk1);
Xn *= p->carp.load_multiplier;
X_last = p->carp.load_multiplier;
P_last = p->carp.load_factor;
p = sourcehash_peers[k - 1];
p->sourcehash.load_multiplier = (Kk1 * (p->sourcehash.load_factor - P_last)) / Xn;
p->sourcehash.load_multiplier += pow(X_last, Kk1);
p->sourcehash.load_multiplier = pow(p->sourcehash.load_multiplier, 1.0 / Kk1);
Xn *= p->sourcehash.load_multiplier;
X_last = p->sourcehash.load_multiplier;
P_last = p->sourcehash.load_factor;
}
}

void
carpRegisterWithCacheManager(CacheManager & manager)
peerSourceHashRegisterWithCacheManager(CacheManager & manager)
{
manager.registerAction("carp", "CARP information", carpCachemgr, 0, 1);
manager.registerAction("sourcehash", "CARP information", peerSourceHashCachemgr, 0, 1);
}

peer *
carpSelectParent(HttpRequest * request)
peerSourceHashSelectParent(HttpRequest * request)
{
int k;
const char *c;
Expand All @@ -170,25 +170,25 @@ carpSelectParent(HttpRequest * request)
const char *key = NULL;
char ntoabuf[MAX_IPSTRLEN];

if (n_carp_peers == 0)
if (n_sourcehash_peers == 0)
return NULL;

key = request->client_addr.NtoA(ntoabuf, sizeof(ntoabuf));

/* calculate hash key */
debugs(39, 2, "carpSelectParent: Calculating hash for " << key);
debugs(39, 2, "peerSourceHashSelectParent: Calculating hash for " << key);

for (c = key; *c != 0; c++)
user_hash += ROTATE_LEFT(user_hash, 19) + *c;

/* select peer */
for (k = 0; k < n_carp_peers; k++) {
tp = carp_peers[k];
combined_hash = (user_hash ^ tp->carp.hash);
for (k = 0; k < n_sourcehash_peers; k++) {
tp = sourcehash_peers[k];
combined_hash = (user_hash ^ tp->sourcehash.hash);
combined_hash += combined_hash * 0x62531965;
combined_hash = ROTATE_LEFT(combined_hash, 21);
score = combined_hash * tp->carp.load_multiplier;
debugs(39, 3, "carpSelectParent: " << tp->name << " combined_hash " << combined_hash <<
score = combined_hash * tp->sourcehash.load_multiplier;
debugs(39, 3, "peerSourceHashSelectParent: " << tp->name << " combined_hash " << combined_hash <<
" score " << std::setprecision(0) << score);

if ((score > high_score) && peerHTTPOkay(tp, request)) {
Expand All @@ -198,13 +198,13 @@ carpSelectParent(HttpRequest * request)
}

if (p)
debugs(39, 2, "carpSelectParent: selected " << p->name);
debugs(39, 2, "peerSourceHashSelectParent: selected " << p->name);

return p;
}

static void
carpCachemgr(StoreEntry * sentry)
peerSourceHashCachemgr(StoreEntry * sentry)
{
peer *p;
int sumfetches = 0;
Expand All @@ -220,9 +220,9 @@ carpCachemgr(StoreEntry * sentry)

for (p = Config.peers; p; p = p->next) {
storeAppendPrintf(sentry, "%24s %10x %10f %10f %10f\n",
p->name, p->carp.hash,
p->carp.load_multiplier,
p->carp.load_factor,
p->name, p->sourcehash.hash,
p->sourcehash.load_multiplier,
p->sourcehash.load_factor,
sumfetches ? (double) p->stats.fetches / sumfetches : -1.0);
}
}
Loading

0 comments on commit f7e1d9c

Please sign in to comment.