Fix TM2 DS match to not loop Fixes Traffic Monitor 2.0 delivery service matching from ATS astats to be a direct hash lookup, instead of a looped string compare. This is a massive CPU gain, profiling it appeared to be up to 30% of the entire app's CPU usage.
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/a722d929 Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/a722d929 Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/a722d929 Branch: refs/heads/master Commit: a722d929bdd658bd22ec0fa1724d9f5762efe5ff Parents: 129a47e Author: Robert Butts <robert.o.bu...@gmail.com> Authored: Fri Jan 27 13:33:24 2017 -0700 Committer: Dave Neuman <neu...@apache.org> Committed: Mon Jan 30 08:28:47 2017 -0700 ---------------------------------------------------------------------- traffic_monitor_golang/traffic_monitor/cache/cache.go | 11 ++++++++--- .../traffic_monitor/trafficopsdata/trafficopsdata.go | 11 +++++------ 2 files changed, 13 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a722d929/traffic_monitor_golang/traffic_monitor/cache/cache.go ---------------------------------------------------------------------- diff --git a/traffic_monitor_golang/traffic_monitor/cache/cache.go b/traffic_monitor_golang/traffic_monitor/cache/cache.go index 46cd68f..7436d2b 100644 --- a/traffic_monitor_golang/traffic_monitor/cache/cache.go +++ b/traffic_monitor_golang/traffic_monitor/cache/cache.go @@ -421,17 +421,22 @@ func processStatPlugin(server enum.CacheName, stats map[enum.DeliveryServiceName } func processStatPluginRemapStats(server enum.CacheName, stats map[enum.DeliveryServiceName]dsdata.Stat, toData todata.TOData, stat string, statParts []string, value interface{}, timeReceived time.Time) (map[enum.DeliveryServiceName]dsdata.Stat, error) { - if len(statParts) < 2 { + if len(statParts) < 3 { return stats, fmt.Errorf("stat has no remap_stats deliveryservice and name parts") } - fqdn := strings.Join(statParts[:len(statParts)-1], ".") + // the FQDN is `subsubdomain`.`subdomain`.`domain`. For a HTTP delivery service, `subsubdomain` will be the cache hostname; for a DNS delivery service, it will be `edge`. Then, `subdomain` is the delivery service regex. + subsubdomain := statParts[0] + subdomain := statParts[1] + domain := strings.Join(statParts[2:len(statParts)-1], ".") - ds, ok := toData.DeliveryServiceRegexes.DeliveryService(fqdn) + ds, ok := toData.DeliveryServiceRegexes.DeliveryService(domain, subdomain, subsubdomain) if !ok { + fqdn := fmt.Sprintf("%s.%s.%s", subsubdomain, subdomain, domain) return stats, fmt.Errorf("ERROR no delivery service match for fqdn '%v' stat '%v'\n", fqdn, strings.Join(statParts, ".")) } if ds == "" { + fqdn := fmt.Sprintf("%s.%s.%s", subsubdomain, subdomain, domain) return stats, fmt.Errorf("ERROR EMPTY delivery service fqdn %v stat %v\n", fqdn, strings.Join(statParts, ".")) } http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a722d929/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go ---------------------------------------------------------------------- diff --git a/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go b/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go index 69c7af1..afc6106 100644 --- a/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go +++ b/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go @@ -43,14 +43,13 @@ type Regexes struct { } // DeliveryService returns the delivery service which matches the given fqdn, or false. -func (d Regexes) DeliveryService(fqdn string) (enum.DeliveryServiceName, bool) { - if ds, ok := d.DirectMatches[fqdn]; ok { +func (d Regexes) DeliveryService(domain, subdomain, subsubdomain string) (enum.DeliveryServiceName, bool) { + if ds, ok := d.DotStartSlashDotFooSlashDotDotStar[subdomain]; ok { return ds, true } - for matchStr, ds := range d.DotStartSlashDotFooSlashDotDotStar { - if strings.Contains(fqdn, "."+matchStr+".") { - return ds, true - } + fqdn := fmt.Sprintf("%s.%s.%s", subsubdomain, subdomain, domain) + if ds, ok := d.DirectMatches[fqdn]; ok { + return ds, true } for regex, ds := range d.RegexMatch { if regex.MatchString(fqdn) {