From: rousskov <> Date: Thu, 9 Apr 1998 04:51:13 +0000 (+0000) Subject: - added peer_digest.o X-Git-Tag: SQUID_3_0_PRE1~3552 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26b164ac83cf389215621005dbe69a664c08ac20;p=thirdparty%2Fsquid.git - added peer_digest.o - a lot of digest related coding and fixes - new stats (mgr:digest_stats) --- diff --git a/src/client_side.cc b/src/client_side.cc index a852451d85..9daa6dbd42 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.264 1998/04/08 21:38:36 wessels Exp $ + * $Id: client_side.cc,v 1.265 1998/04/08 22:51:13 rousskov Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -577,22 +577,29 @@ clientUpdateCounters(clientHttpRequest * http) assert(H->alg == PEER_SA_NONE); } if (/* we used ICP or CD for peer selecton */ - H->alg != PEER_SA_NONE && - /* a CD lookup found peers with digests */ - H->cd_lookup != LOOKUP_NONE && + http->request->hier.alg != PEER_SA_NONE && + /* a successful CD lookup was made */ + http->request->hier.cd_lookup != LOOKUP_NONE && + /* it was not a CD miss (we go direct on CD MISSes) */ + !(http->request->hier.alg == PEER_SA_DIGEST && http->request->hier.cd_lookup == LOOKUP_MISS) && /* paranoid: we have a reply pointer */ (reply = storeEntryReply(http->entry))) { const char *x_cache_fld = httpHeaderGetLastStr(&reply->header, HDR_X_CACHE); const int real_hit = x_cache_fld && !strncmp(x_cache_fld, "HIT", 3); - const int guess_hit = H->cd_lookup == LOOKUP_HIT; - peer *peer = peerFindByName(H->host); + const int guess_hit = LOOKUP_HIT == http->request->hier.cd_lookup; + peer *peer = peerFindByName(http->request->hier.cd_host); + debug(33,2) ("clientUpdateCounters: peer %s real/guess: %d/%d for %s!\n", + http->request->hier.cd_host, real_hit, guess_hit, http->request->host); cacheDigestGuessStatsUpdate(&Counter.cd.guess, real_hit, guess_hit); if (peer) cacheDigestGuessStatsUpdate(&peer->digest.stats.guess, real_hit, guess_hit); - else - debug(33,1) ("clientUpdateCounters: lost peer: %s!\n", storeUrl(http->entry)); + else { + debug(33,2) ("clientUpdateCounters: lost peer %s for %s!\n", + http->request->hier.cd_host, http->request->host); + fatal_dump("lost peer"); + } } #endif } diff --git a/src/enums.h b/src/enums.h index 9949f6b887..71a7d1e65a 100644 --- a/src/enums.h +++ b/src/enums.h @@ -263,6 +263,7 @@ typedef enum { ROUNDROBIN_PARENT, #if SQUID_PEER_DIGEST CACHE_DIGEST_HIT, + CACHE_DIGEST_MISS_DIRECT, #endif HIER_MAX } hier_code; diff --git a/src/neighbors.cc b/src/neighbors.cc index 0b2d2845a7..18e2b651ee 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,6 +1,6 @@ /* - * $Id: neighbors.cc,v 1.194 1998/04/07 23:44:17 rousskov Exp $ + * $Id: neighbors.cc,v 1.195 1998/04/08 22:51:14 rousskov Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -547,6 +547,43 @@ neighborsUdpPing(request_t * request, return peers_pinged; } +/* lookup the digest of a given peer */ +lookup_t +peerDigestLookup(peer *p, request_t * request, StoreEntry * entry) +{ +#if SQUID_PEER_DIGEST + const cache_key *key = storeKeyPublic(storeUrl(entry), request->method); + assert(p); + debug(15, 5) ("neighborsDigestPeerLookup: peer %s\n", p->host); + /* does the peeer have a valid digest? */ + if (EBIT_TEST(p->digest.flags, PD_DISABLED)) { + return LOOKUP_NONE; + } else + if (!peerAllowedToUse(p, request)) { + return LOOKUP_NONE; + } else + if (EBIT_TEST(p->digest.flags, PD_USABLE)) { + /* fall through; put here to have common case on top */; + } else + if (!EBIT_TEST(p->digest.flags, PD_INITED)) { + peerDigestInit(p); + return LOOKUP_NONE; + } else { + assert(EBIT_TEST(p->digest.flags, PD_REQUESTED)); + return LOOKUP_NONE; + } + debug(15, 5) ("neighborsDigestPeerLookup: OK to lookup peer %s\n", p->host); + assert(p->digest.cd); + /* does digest predict a hit? */ + if (!cacheDigestTest(p->digest.cd, key)) + return LOOKUP_MISS; + debug(15, 5) ("neighborsDigestPeerLookup: peer %s says HIT!\n", p->host); + return LOOKUP_HIT; +#endif + return LOOKUP_NONE; +} + +/* select best peer based on cache digests */ peer * neighborsDigestSelect(request_t * request, StoreEntry * entry) { @@ -562,33 +599,19 @@ neighborsDigestSelect(request_t * request, StoreEntry * entry) key = storeKeyPublic(storeUrl(entry), request->method); for (i = 0, p = first_ping; i++ < Config.npeers; p = p->next) { + lookup_t lookup; if (!p) p = Config.peers; if (i == 1) first_ping = p; - debug(15, 5) ("neighborsDigestSelect: considering peer %s\n", p->host); - /* does the peeer have a valid digest? */ - if (EBIT_TEST(p->digest.flags, PD_DISABLED)) { - continue; - } else - if (EBIT_TEST(p->digest.flags, PD_USABLE)) { - ; - } else - if (!EBIT_TEST(p->digest.flags, PD_INITED)) { - peerDigestInit(p); + lookup = peerDigestLookup(p, request, entry); + if (lookup == LOOKUP_NONE) continue; - } else { - assert(EBIT_TEST(p->digest.flags, PD_REQUESTED)); - continue; - } choice_count++; - debug(15, 5) ("neighborsDigestSelect: peer %s is a candidate\n", p->host); - assert(p->digest.cd); - /* does digest predict a hit? */ - if (!cacheDigestTest(p->digest.cd, key)) + if (lookup == LOOKUP_MISS) continue; - p_rtt = netdbHostPeerRtt(request->host, p); - debug(15, 5) ("neighborsDigestSelect: peer %s says hit with rtt %d\n", + p_rtt = netdbHostRtt(p->host); + debug(15, 5) ("neighborsDigestSelect: peer %s rtt: %d\n", p->host, p_rtt); /* is this peer better than others in terms of rtt ? */ if (!best_p || (p_rtt && p_rtt < best_rtt)) { @@ -600,14 +623,30 @@ neighborsDigestSelect(request_t * request, StoreEntry * entry) p->host, best_rtt); } } - debug(15, 5) ("neighborsDigestSelect: selected peer %s, rtt: %d\n", - best_p ? best_p->host : "", best_rtt); + debug(15, 4) ("neighborsDigestSelect: choices: %d (%d)\n", + choice_count, ichoice_count); + peerNoteDigestLookup(request, best_p, + best_p ? LOOKUP_HIT : (choice_count ? LOOKUP_MISS : LOOKUP_NONE)); request->hier.n_choices = choice_count; request->hier.n_ichoices = ichoice_count; #endif return best_p; } +void +peerNoteDigestLookup(request_t * request, peer *p, lookup_t lookup) +{ +#if SQUID_PEER_DIGEST + if (p) + strncpy(request->hier.cd_host, p->host, sizeof(request->hier.cd_host)); + else + *request->hier.cd_host = '\0'; + request->hier.cd_lookup = lookup; + debug(15, 4) ("peerNoteDigestLookup: peer %s, lookup: %s\n", + p ? p->host : "", lookup_t_str[lookup]); +#endif +} + static void neighborAlive(peer * p, const MemObject * mem, const icp_common_t * header) { diff --git a/src/peer_select.cc b/src/peer_select.cc index 54b35e9cdb..a2b20e0d55 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -1,6 +1,6 @@ /* - * $Id: peer_select.cc,v 1.46 1998/04/08 19:28:48 wessels Exp $ + * $Id: peer_select.cc,v 1.47 1998/04/08 22:51:15 rousskov Exp $ * * DEBUG: section 44 Peer Selection Algorithm * AUTHOR: Duane Wessels @@ -49,6 +49,7 @@ const char *hier_strings[] = "ROUNDROBIN_PARENT", #if SQUID_PEER_DIGEST "CACHE_DIGEST_HIT", + "CACHE_DIGEST_MISS", #endif "INVALID CODE" }; @@ -307,35 +308,34 @@ peerSelectFoo(ps_state * psstate) } else if (peerSelectIcpPing(request, direct, entry)) { assert(entry->ping_status == PING_NONE); #if SQUID_PEER_DIGEST - /* always check digests if any */ - /* @?@ optimize: track if there are any digested peers at all (global counter) */ - if (1) { - p = neighborsDigestSelect(request, entry); - if (p) { - request->hier.cd_lookup = LOOKUP_HIT; - } else - if (request->hier.n_choices) { - request->hier.cd_lookup = LOOKUP_MISS; - } else { - request->hier.cd_lookup = LOOKUP_NONE; - } - debug(44, 3) ("peerSelect: %s digest lookup: %s choices: %d (%d)\n", - p ? p->host : "", - lookup_t_str[request->hier.cd_lookup], - request->hier.n_choices, request->hier.n_ichoices); - } - /* @?@ TEST: randomly choose a peer selection algorithm */ - if (request->hier.cd_lookup != LOOKUP_NONE && (squid_random() & 1)) { + /* which algorithm to use? */ + if (squid_random() & 1) { debug(44, 3) ("peerSelect: Using Cache Digest\n"); request->hier.alg = PEER_SA_DIGEST; - if (request->hier.cd_lookup == LOOKUP_HIT) { + if (1 /* global_digested_peer_count */) + p = neighborsDigestSelect(request, entry); + code = DIRECT; /* default @?@: CACHE_DIGEST_NONE */ + switch (request->hier.cd_lookup) { + case LOOKUP_HIT: assert(p); code = CACHE_DIGEST_HIT; debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host); hierarchyNote(&request->hier, code, &psstate->icp, p->host); + peerSelectCallback(psstate, p); /* @?@: p used to be NULL */ + return; + case LOOKUP_MISS: + code = CACHE_DIGEST_MISS_DIRECT; + /* fall through */ + case LOOKUP_NONE: + /* go direct */ + debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], request->host); + hierarchyNote(&request->hier, code, &psstate->icp, request->host); peerSelectCallback(psstate, NULL); return; + default: + assert(0); /* invalid lookup code */ } + assert(0); /* never reached */ } else { request->hier.alg = PEER_SA_ICP; #endif @@ -456,6 +456,11 @@ peerHandleIcpReply(peer * p, peer_t type, icp_common_t * header, void *data) debug(44, 3) ("peerHandleIcpReply: %s %s\n", icp_opcode_str[op], storeUrl(psstate->entry)); +#if SQUID_PEER_DIGEST + /* do cd lookup to count false misses */ + peerNoteDigestLookup(request, p, + peerDigestLookup(p, request, psstate->entry)); +#endif psstate->icp.n_recv++; if (op == ICP_MISS || op == ICP_DECHO) { if (type == PEER_PARENT) diff --git a/src/protos.h b/src/protos.h index 1ded7869e6..37f6cc9b4c 100644 --- a/src/protos.h +++ b/src/protos.h @@ -485,7 +485,9 @@ extern void neighbors_open(int); extern peer *peerFindByName(const char *); extern peer *getDefaultParent(request_t * request); extern peer *getRoundRobinParent(request_t * request); +extern lookup_t peerDigestLookup(peer *p, request_t * request, StoreEntry * entry); extern peer *neighborsDigestSelect(request_t * request, StoreEntry * entry); +extern void peerNoteDigestLookup(request_t * request, peer *p, lookup_t lookup); extern int neighborUp(const peer * e); extern void peerDestroy(peer * e); extern char *neighborTypeStr(const peer * e); @@ -515,8 +517,7 @@ extern peer *peerGetSomeParent(request_t *, hier_code *); extern void peerSelectInit(void); /* peer_digest.c */ -extern void peerDigestValidate(peer * p); -extern void peerDigestRequest(peer * p); +void peerDigestInit(peer *p); extern void protoDispatch(int, StoreEntry *, request_t *); diff --git a/src/stat.cc b/src/stat.cc index 5eeee9d483..a3a0aa5aff 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -1,6 +1,6 @@ /* - * $Id: stat.cc,v 1.226 1998/04/08 19:28:50 wessels Exp $ + * $Id: stat.cc,v 1.227 1998/04/08 22:51:16 rousskov Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -129,6 +129,7 @@ static OBJH info_get; static OBJH statFiledescriptors; static OBJH statCounters; static OBJH statPeerSelect; +static OBJH statDigestBlob; static OBJH statAvg5min; static OBJH statAvg60min; static OBJH statUtilization; @@ -766,6 +767,9 @@ statInit(void) cachemgrRegister("peer_select", "Peer Selection Algorithms", statPeerSelect, 0); + cachemgrRegister("digest_stats", + "Cache Digest and ICP blob", + statDigestBlob, 0); cachemgrRegister("5min", "5 Minute Average of Counters", statAvg5min, 0); @@ -1029,6 +1033,61 @@ statPeerSelect(StoreEntry * sentry) #endif } +static void +statDigestBlob(StoreEntry * sentry) +{ +#if SQUID_PEER_DIGEST + StatCounters *f = &CountHist[0]; + StatCounters *l = &CountHist[5]; + double x; + + storeAppendPrintf(sentry, "\nicp.query_svc_time histogram:\n"); + statHistDump(&f->icp.query_svc_time, sentry, NULL); + storeAppendPrintf(sentry, "\nicp.reply_svc_time histogram:\n"); + statHistDump(&f->icp.reply_svc_time, sentry, NULL); + storeAppendPrintf(sentry, "\nicp.client_svc_time histogram:\n"); + statHistDump(&f->icp.client_svc_time, sentry, NULL); + storeAppendPrintf(sentry, "\ncd.client_svc_time histogram:\n"); + statHistDump(&f->cd.client_svc_time, sentry, NULL); + + storeAppendPrintf(sentry, "\nMedian service times:\n"); + x = statHistDeltaMedian(&l->cd.client_svc_time, + &f->cd.client_svc_time); + storeAppendPrintf(sentry, "cd.client_median_svc_time = %f seconds\n", + x / 1000.0); + x = statHistDeltaMedian(&l->icp.client_svc_time, + &f->icp.client_svc_time); + storeAppendPrintf(sentry, "icp.client_median_svc_time = %f seconds\n", + x / 1000.0); + + storeAppendPrintf(sentry, "\nTraffic:\n"); + storeAppendPrintf(sentry, "icp.times_used = %d\n", + f->icp.times_used); + storeAppendPrintf(sentry, "icp.pkts_sent = %d\n", + f->icp.pkts_sent); + storeAppendPrintf(sentry, "icp.pkts_recv = %d\n", + f->icp.pkts_recv); + storeAppendPrintf(sentry, "icp.replies_queued = %d\n", + f->icp.replies_queued); + storeAppendPrintf(sentry, "icp.kbytes_sent = %d\n", + (int) f->icp.kbytes_sent.kb); + storeAppendPrintf(sentry, "icp.kbytes_recv = %d\n", + (int) f->icp.kbytes_recv.kb); + storeAppendPrintf(sentry, "cd.times_used = %d\n", + f->cd.times_used); + storeAppendPrintf(sentry, "cd.kbytes_sent = %d\n", + (int) f->cd.kbytes_sent.kb); + storeAppendPrintf(sentry, "cd.kbytes_recv = %d\n", + (int) f->cd.kbytes_recv.kb); + storeAppendPrintf(sentry, "cd.peer_memory = %d\n", + (int) f->cd.memory.kb); + storeAppendPrintf(sentry, "cd.store_memory = %d\n", + (int) (store_digest ? store_digest->mask_size/1024 : 0)); +#endif + statPeerSelect(sentry); + storeDigestReport(sentry); +} + static void statCounters(StoreEntry * e) { diff --git a/src/store_digest.cc b/src/store_digest.cc index 34c6c01d27..71e4e2c76a 100644 --- a/src/store_digest.cc +++ b/src/store_digest.cc @@ -1,5 +1,5 @@ /* - * $Id: store_digest.cc,v 1.4 1998/04/07 23:26:46 rousskov Exp $ + * $Id: store_digest.cc,v 1.5 1998/04/08 22:51:17 rousskov Exp $ * * DEBUG: section 71 Store Digest Manager * AUTHOR: Alex Rousskov @@ -48,9 +48,9 @@ typedef struct { */ /* how often we want to rebuild the digest, seconds */ -static const time_t StoreDigestRebuildPeriod = 60 * 60; +static const time_t StoreDigestRebuildPeriod = 6 * 60; /* how often we want to rewrite the digest, seconds */ -static const time_t StoreDigestRewritePeriod = 60 * 60; +static const time_t StoreDigestRewritePeriod = 6 * 60; /* how many bytes to swap out at a time */ static const int StoreDigestSwapOutChunkSize = SM_PAGE_SIZE; /* portion (0,1] of a hash table to be rescanned at a time */ diff --git a/src/structs.h b/src/structs.h index 95cfd387b2..d4bd9701ba 100644 --- a/src/structs.h +++ b/src/structs.h @@ -617,6 +617,7 @@ struct _HierarchyLogEntry { char host[SQUIDHOSTNAMELEN]; icp_ping_data icp; #if SQUID_PEER_DIGEST + char cd_host[SQUIDHOSTNAMELEN]; /* the host of selected by cd peer */ peer_select_alg_t alg; /* peer selection algorithm */ lookup_t cd_lookup; /* cd prediction: none, miss, hit */ int n_choices; /* #peers we selected from (cd only) */ @@ -1200,8 +1201,8 @@ struct _StatCounters { #if SQUID_PEER_DIGEST struct { int times_used; - kb_t kbtes_sent; - kb_t kbtes_recv; + kb_t kbytes_sent; + kb_t kbytes_recv; kb_t memory; cd_guess_stats guess; StatHist client_svc_time;