]> git.ipfire.org Git - thirdparty/pdns.git/commit
Introducing TCounters
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 8 Nov 2022 10:10:54 +0000 (11:10 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 12 Dec 2022 12:14:02 +0000 (13:14 +0100)
commit7d3d2f4f5a441537748f9e271260c5f9a1f35ca2
tree5945100cf516f535ac11f2d4aed87d118f654478
parent6569520ec1286f5d9bed93fe3811bdd9e785d351
Introducing TCounters

This is a mostly lockless (and not using atomics) way to keep track of
counters and other metrics.

Atomic value are more expensive than you would think (especially if
your platform has no native atomic support for your data type), and
using locking all the time for often updated counters is very
expensive as well.

The idea for `TCounters` is based on

https://github.com/ahupowerdns/mcounter

But addresses the issues raised in
https://github.com/ahupowerdns/mcounter/issues/3

Templates are used, the application has to provide a specific class to
hold the values and enums to index these values.  The application
specific class also has to provide a `merge()` method to merge two
instances of the application specific data.  For counters that is
simple: just add them. Averages (or histogrfam) requires a bit more
work. This is demonstrated in `rec-tcounters.{cc,hh}`

At the end of a body of work the application's threads should call the
`updateSnap()` function. If a certain amount of time has passed since
the last time, a thread local snapshot of the thread local data will
be created in a thread-safe way.

The class that collects the aggregated values reads (also in a thread
safe way) from the snapshot values in each thread.

Updates of individual counters are done on thread-local data,
potentially many times per second. The snaps contain a consistent set
of the values and are taken by default once per 100ms, so reletively
seldom.

By using the snap mnechanism the aggragate values computed are based
on internally consistent counter values (as long as related counters
are updated from the same thread). A (small) drawback is that the
values computed might be a bit out of date.

The snapshot approach was suggested by @wojas.

This PR de demonstrates `TCounters` for a few Recursor metrics: simple
counters and double typed average values. For the latter weights are
kept, so that the average of averages can be computed in a proper way.
21 files changed:
pdns/histogram.hh
pdns/lwres.cc
pdns/pdns_recursor.cc
pdns/rec_channel_rec.cc
pdns/recursordist/Makefile.am
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-main.hh
pdns/recursordist/rec-tcounters.cc [new file with mode: 0644]
pdns/recursordist/rec-tcounters.hh [new file with mode: 0644]
pdns/recursordist/rec-tcp.cc
pdns/recursordist/tcounters.hh [new symlink]
pdns/recursordist/test-rec-tcounters_cc.cc [new file with mode: 0644]
pdns/recursordist/test-syncres_cc.cc
pdns/syncres.cc
pdns/syncres.hh
pdns/tcounters.hh [new file with mode: 0644]
regression-tests.recursor-dnssec/recursortests.py
regression-tests.recursor-dnssec/test_AggressiveNSECCache.py
regression-tests.recursor-dnssec/test_RootNXTrust.py
regression-tests.recursor-dnssec/test_SimpleDoT.py
regression-tests.recursor-dnssec/test_SimpleForwardOverDoT.py