]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
- added peer_digest.o
authorrousskov <>
Thu, 9 Apr 1998 04:51:13 +0000 (04:51 +0000)
committerrousskov <>
Thu, 9 Apr 1998 04:51:13 +0000 (04:51 +0000)
- a lot of digest related coding and fixes
- new stats (mgr:digest_stats)

src/client_side.cc
src/enums.h
src/neighbors.cc
src/peer_select.cc
src/protos.h
src/stat.cc
src/store_digest.cc
src/structs.h

index a852451d85ec21562ea90daa56142ecef2652a77..9daa6dbd429f2e5e25b6a06135d4dde05934d0bf 100644 (file)
@@ -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
 }
index 9949f6b88749f7384522f7199f3e905df9064a7e..71a7d1e65a4ae589641df2281668229b96166305 100644 (file)
@@ -263,6 +263,7 @@ typedef enum {
     ROUNDROBIN_PARENT,
 #if SQUID_PEER_DIGEST
     CACHE_DIGEST_HIT,
+    CACHE_DIGEST_MISS_DIRECT,
 #endif
     HIER_MAX
 } hier_code;
index 0b2d2845a75d24fdfcf63a27a0251da5ad0ddb3a..18e2b651ee47eaeee52bb3f02c66bc43782d5b3d 100644 (file)
@@ -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 : "<none>", 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 : "<none>", lookup_t_str[lookup]);
+#endif
+}
+
 static void
 neighborAlive(peer * p, const MemObject * mem, const icp_common_t * header)
 {
index 54b35e9cdb1077fdc0fbadaef641c22ffb0536f1..a2b20e0d55b7e83b446d8c20465d73e21ef6014c 100644 (file)
@@ -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)
index 1ded7869e6fd93b8ddda45e08eed890a6d353fb8..37f6cc9b4c24c782b1475f96d50990e1e7a73b26 100644 (file)
@@ -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 *);
 
index 5eeee9d48319699031ed114b0e8a3ba41eb626ba..a3a0aa5aff215f57256edd7815024d79428f8e71 100644 (file)
@@ -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)
 {
index 34c6c01d27f0fd9fd634849363946110fd9a9a24..71e4e2c76a835b5dfc26092e3125e479e84a49b6 100644 (file)
@@ -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 */
index 95cfd387b2a398ce89dcbd2d05a741ad9c6a5200..d4bd9701bacec3349955fc32a0256f65fb10e756 100644 (file)
@@ -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;