BIND 10 #2154: Create a set of counters to hold auth statistics items

BIND 10 Development do-not-reply at isc.org
Fri Aug 24 22:44:21 UTC 2012


#2154: Create a set of counters to hold auth statistics items
-------------------------------------+-------------------------------------
                   Reporter:         |                 Owner:  jelte
  y-aharen                           |                Status:  reviewing
                       Type:         |             Milestone:
  enhancement                        |  Sprint-20120904
                   Priority:         |            Resolution:
  medium                             |             Sensitive:  0
                  Component:         |           Sub-Project:  DNS
  b10-auth                           |  Estimated Difficulty:  8
                   Keywords:         |           Total Hours:  0
            Defect Severity:  N/A    |
Feature Depending on Ticket:         |
        Add Hours to Ticket:  0      |
                  Internal?:  0      |
-------------------------------------+-------------------------------------

Comment (by jinmei):

 In an attempt of reviewing #2157, a number of questions and concerns
 occurred to me, and I realized they are mainly related to this ticket.
 So I'm making my own comments here.

 I have some concerns with the current approach implemented in this
 branch, mainly related to scalability and (per query/request) update
 performance.

 Regarding scalability, I also don't think it makes much sense to
 define enum for each known RR type.  Also, the large if block in
 `CountersImpl::inc` makes the code unreadable and possibly less
 efficient (large functions generally make it slower.  Many 'if-else's
 are also not performance friendly).

 I'm also not sure if it makes sense to collect attributes first and
 then update the corresponding statistics counters.  This two-stage
 operation has its own overhead, and we need to have yet another set of
 if-else's in CountersImpl::inc().

 Essentially, statistics counters are a simple mapping from "some ID"
 to an integer, so things like
 {{{#!cpp
                 stats_attrs.setQueryDO(edns->getDNSSECAwareness());
                 // and eventually do this in CountersImpl::inc().
     if (qrattrs.req_is_dnssec_ok_) {
         server_qr_counter_.inc(QR_REQUEST_DNSSEC_OK);
     }
 }}}
 could be a simple increment of an element in an array or vector:
 {{{#!cpp
     if (edns->getDNSSECAwareness()) {
         ++server_counters_[QR_REQUEST_DNSSEC_OK];
     }
 }}}
 It would still probably be a good idea to have some level of
 abstraction for safety and (possibly) better extendability, but I'd
 like to minimize the overhead of incrementing a statistics counter as
 small as this simplest one.

 So, if I were to implement this stuff, I'd probably do something like
 this:
 - for generic counters, we use a simple array-type abstraction to
   represent a set of counters.  define enum to indicate specific index
   of the array for a specific statistics counter.  when incrementing
   it, almost directly refer to the array and just do ++
 - for some other DNS specific counters, i.e., per RR type, rcode,
   opcode, define separate simple counter class.  It's also basically a
   simple indexed array, but each class knows how to identify the array
   index for a specific (RRType/Rcode/Opcode/etc) object.  In many
   cases it should be a trivial conversion.  For `RRType`, depending on
   how specific we want to be, we might even make the array
   "extendable" and extend it as we see any uncommon type (but even if
   it makes sense that's beyond the scope of the initial work).  Each
   class also knows how to convert the counters to a JSON format so
   that it can be used to send via a CC channel.

 And, one other minor point I happen to notice.  If we do it:
 {{{#!cpp
         // statistics: check EDNS
         //     note: This can only be reliable after TSIG check succeeds.
         {
             ConstEDNSPtr edns = message.getEDNS();
             if (edns != NULL) {
                 stats_attrs.setQueryEDNS(true, edns->getVersion() == 0);
                 stats_attrs.setQueryDO(edns->getDNSSECAwareness());
             }
         }
 }}}
 I'd pass this `edns` to processNormalQuery (in any case, the outer
 most braces shouldn't be necessary).

 Finally, I'd suggest you check the performance impact on various
 possible approaches using e.g. query_bench.  Maybe my concerns above
 might be marginal in the total overhead of query processing.

-- 
Ticket URL: <http://bind10.isc.org/ticket/2154#comment:10>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list