Skip to content

Commit 6602253

Browse files
cvuosaloyadij
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 1f9b227 commit 6602253

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
@@ -85,6 +85,7 @@ Thank you!
8585
Brian Degenhardt <bmd@mp3.com>
8686
Brian Denehy <B-Denehy@adfa.oz.au>
8787
Bruce Murphy <pack-squid@rattus.net>
88+
Carl Vuosalo <cvuosalo@cern.ch>
8889
Carson Gaspar <carson@cs.columbia.edu>
8990
Carson Gaspar <carson@lehman.com>
9091
Carsten Grzemba <cgrzemba@opencsw.org>

src/MemStore.cc

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

208208
stats.mem.shared = true;
209+
210+
// In SMP mode, only the first worker reports shared memory stats to avoid
211+
// adding up same-cache positive stats (reported by multiple worker
212+
// processes) when Coordinator aggregates worker-reported stats.
213+
// See also: Store::Disk::doReportStat().
214+
if (UsingSmp() && KidIdentifier != 1)
215+
return;
216+
209217
stats.mem.capacity =
210218
Ipc::Mem::PageLimit(Ipc::Mem::PageId::cachePage) * pageSize;
211219
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
@@ -24,6 +24,8 @@
2424
#include "StatCounters.h"
2525
#include "StatHist.h"
2626
#include "Store.h"
27+
#include "store/Controller.h"
28+
#include "StoreStats.h"
2729
#include "tools.h"
2830
#include "util.h"
2931

@@ -408,11 +410,14 @@ snmp_prfSysFn(variable_list * Var, snint * ErrP)
408410
SMI_GAUGE32);
409411
break;
410412

411-
case PERF_SYS_NUMOBJCNT:
413+
case PERF_SYS_NUMOBJCNT: {
414+
StoreInfoStats stats;
415+
Store::Root().getStats(stats);
412416
Answer = snmp_var_new_integer(Var->name, Var->name_length,
413-
(snint) StoreEntry::inUseCount(),
417+
(snint) (stats.mem.count + stats.swap.count),
414418
SMI_GAUGE32);
415419
break;
420+
}
416421

417422
default:
418423
*ErrP = SNMP_ERR_NOSUCHNAME;

0 commit comments

Comments
 (0)