Skip to content

Commit d048024

Browse files
cvuosalosquid-anubis
authored andcommitted
Fix SNMP cacheNumObjCount -- number of cached objects (#2053)
SNMP counter cacheNumObjCount used StoreEntry::inUseCount() stats. For Squid instances using a rock cache_dirs or a shared memory cache, the number of StoreEntry objects in use is usually very different from the number of cached objects because these caches do not use StoreEntry objects as a part of their index. For all instances, inUseCount() also includes ongoing transactions and internal tasks that are not related to cached objects at all. We now use the sum of the counters already reported on "on-disk objects" and "Hot Object Cache Items" lines in "Internal Data Structures" section of `mgr:info` cache manager report. Due to floating-point arithmetic, these stats are approximate, but it is best to keep SNMP and cache manager reports consistent. This change does not fix SNMP Gauge32 overflow bug: Caches with 2^32 or more objects continue to report wrong/smaller cacheNumObjCount values. ### On MemStore::getStats() and StoreInfoStats changes To include the number of memory-cached objects while supporting SMP configurations with shared memory caches, we had to change how cache manager code aggregates StoreInfoStats::mem data collected from SMP worker processes. Before these changes, `StoreInfoStats::operator +=()` used a mem.shared data member to trigger special aggregation code hack, but * SNMP-specific code cannot benefit from that StoreInfoStats aggregation because SNMP code exchanges simple counters rather than StoreInfoStats objects. `StoreInfoStats::operator +=()` is never called by SNMP code. Instead, SNMP uses Snmp::Pdu::aggregate() and friends. * We could not accommodate SNMP by simply adding special aggregation hacks directly to MemStore::getStats() because that would break critical "all workers report about the same stats" expectations of the special hack in `StoreInfoStats::operator +=()`. To make both SNMP and cache manager use cases work, we removed the hack from StoreInfoStats::operator +=() and hacked MemStore::getStats() instead, making the first worker responsible for shared memory cache stats reporting (unlike SMP rock diskers, there is no single kid process dedicated to managing a shared memory cache). StoreInfoStats operator now uses natural aggregation logic without hacks. TODO: After these changes, StoreInfoStats::mem.shared becomes essentially unused because it was only used to enable special aggregation hack in StoreInfoStats that no longer exists. Remove?
1 parent cfee98c commit d048024

4 files changed

Lines changed: 20 additions & 18 deletions

File tree

CONTRIBUTORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ Thank you!
8888
Brian Degenhardt <bmd@mp3.com>
8989
Brian Denehy <B-Denehy@adfa.oz.au>
9090
Bruce Murphy <pack-squid@rattus.net>
91+
Carl Vuosalo <cvuosalo@cern.ch>
9192
Carson Gaspar <carson@cs.columbia.edu>
9293
Carson Gaspar <carson@lehman.com>
9394
Carsten Grzemba <cgrzemba@opencsw.org>

src/MemStore.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,14 @@ MemStore::getStats(StoreInfoStats &stats) const
207207
const size_t pageSize = Ipc::Mem::PageSize();
208208

209209
stats.mem.shared = true;
210+
211+
// In SMP mode, only the first worker reports shared memory stats to avoid
212+
// adding up same-cache positive stats (reported by multiple worker
213+
// processes) when Coordinator aggregates worker-reported stats.
214+
// See also: Store::Disk::doReportStat().
215+
if (UsingSmp() && KidIdentifier != 1)
216+
return;
217+
210218
stats.mem.capacity =
211219
Ipc::Mem::PageLimit(Ipc::Mem::PageId::cachePage) * pageSize;
212220
stats.mem.size =

src/StoreStats.cc

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,10 @@ StoreInfoStats::operator +=(const StoreInfoStats &stats)
2323
// Assume that either all workers use shared memory cache or none do.
2424
// It is possible but difficult to report correct stats for an arbitrary
2525
// mix, and only rather unusual deployments can benefit from mixing.
26-
27-
// If workers share memory, we will get shared stats from those workers
28-
// and non-shared stats from other processes. Ignore order and also
29-
// ignore other processes stats because they are zero in most setups.
30-
if (stats.mem.shared) { // workers share memory
31-
// use the latest reported stats, they all should be about the same
32-
mem.shared = true;
33-
mem.size = stats.mem.size;
34-
mem.capacity = stats.mem.capacity;
35-
mem.count = stats.mem.count;
36-
} else if (!mem.shared) { // do not corrupt shared stats, if any
37-
// workers do not share so we must add everything up
38-
mem.size += stats.mem.size;
39-
mem.capacity += stats.mem.capacity;
40-
mem.count += stats.mem.count;
41-
}
26+
mem.shared = mem.shared || stats.mem.shared; // TODO: Remove mem.shared as effectively unused?
27+
mem.size += stats.mem.size;
28+
mem.capacity += stats.mem.capacity;
29+
mem.count += stats.mem.count;
4230

4331
store_entry_count += stats.store_entry_count;
4432
mem_object_count += stats.mem_object_count;

src/snmp_agent.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "StatCounters.h"
2626
#include "StatHist.h"
2727
#include "Store.h"
28+
#include "store/Controller.h"
29+
#include "StoreStats.h"
2830
#include "tools.h"
2931
#include "util.h"
3032

@@ -409,11 +411,14 @@ snmp_prfSysFn(variable_list * Var, snint * ErrP)
409411
SMI_GAUGE32);
410412
break;
411413

412-
case PERF_SYS_NUMOBJCNT:
414+
case PERF_SYS_NUMOBJCNT: {
415+
StoreInfoStats stats;
416+
Store::Root().getStats(stats);
413417
Answer = snmp_var_new_integer(Var->name, Var->name_length,
414-
(snint) StoreEntry::inUseCount(),
418+
(snint) (stats.mem.count + stats.swap.count),
415419
SMI_GAUGE32);
416420
break;
421+
}
417422

418423
default:
419424
*ErrP = SNMP_ERR_NOSUCHNAME;

0 commit comments

Comments
 (0)