Skip to content

Commit 352d49c

Browse files
Optimize the new inhibitor implementation for ~2.5x performance improvement (#4668)
* remove metric selection from inhibitor hot-path Signed-off-by: Ethan Hunter <[email protected]> * add optimizations to improve inhibitor performance Signed-off-by: Ethan Hunter <[email protected]> * fix duration calculation Co-authored-by: Siavash Safi <[email protected]> Signed-off-by: Ethan Hunter <[email protected]> --------- Signed-off-by: Ethan Hunter <[email protected]> Signed-off-by: Ethan Hunter <[email protected]> Co-authored-by: Siavash Safi <[email protected]>
1 parent e6aa7c0 commit 352d49c

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

inhibit/inhibit.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,22 +163,25 @@ func (ih *Inhibitor) Mutes(lset model.LabelSet) bool {
163163
ruleStart := time.Now()
164164
if !r.TargetMatchers.Matches(lset) {
165165
// If target side of rule doesn't match, we don't need to look any further.
166-
r.metrics.matchesDuration.With(prometheus.Labels{"rule": r.Name, "matched": "false"}).Observe(time.Since(ruleStart).Seconds())
166+
r.metrics.matchesDurationNotMatched.Observe(time.Since(ruleStart).Seconds())
167167
continue
168168
}
169-
r.metrics.matchesDuration.With(prometheus.Labels{"rule": r.Name, "matched": "true"}).Observe(time.Since(ruleStart).Seconds())
169+
r.metrics.matchesDurationMatched.Observe(time.Since(ruleStart).Seconds())
170170
// If we are here, the target side matches. If the source side matches, too, we
171171
// need to exclude inhibiting alerts for which the same is true.
172-
if inhibitedByFP, eq := r.hasEqual(lset, r.SourceMatchers.Matches(lset)); eq {
172+
if inhibitedByFP, eq := r.hasEqual(lset, r.SourceMatchers.Matches(lset), ruleStart); eq {
173173
ih.marker.SetInhibited(fp, inhibitedByFP.String())
174-
ih.metrics.mutesDuration.With(prometheus.Labels{"muted": "true"}).Observe(time.Since(start).Seconds())
175-
r.metrics.mutesDuration.With(prometheus.Labels{"rule": r.Name, "muted": "true"}).Observe(time.Since(ruleStart).Seconds())
174+
now := time.Now()
175+
sinceStart := now.Sub(start)
176+
sinceRuleStart := now.Sub(ruleStart)
177+
ih.metrics.mutesDurationMuted.Observe(sinceStart.Seconds())
178+
r.metrics.mutesDurationMuted.Observe(sinceRuleStart.Seconds())
176179
return true
177180
}
178-
r.metrics.mutesDuration.With(prometheus.Labels{"rule": r.Name, "muted": "false"}).Observe(time.Since(ruleStart).Seconds())
181+
r.metrics.mutesDurationNotMuted.Observe(time.Since(ruleStart).Seconds())
179182
}
180183
ih.marker.SetInhibited(fp)
181-
ih.metrics.mutesDuration.With(prometheus.Labels{"muted": "false"}).Observe(time.Since(start).Seconds())
184+
ih.metrics.mutesDurationNotMuted.Observe(time.Since(start).Seconds())
182185

183186
return false
184187
}
@@ -360,8 +363,7 @@ func (r *InhibitRule) gcCallback(alerts []types.Alert) {
360363
// labels for the given label set. If so, the fingerprint of one of those alerts
361364
// is returned. If excludeTwoSidedMatch is true, alerts that match both the
362365
// source and the target side of the rule are disregarded.
363-
func (r *InhibitRule) hasEqual(lset model.LabelSet, excludeTwoSidedMatch bool) (model.Fingerprint, bool) {
364-
now := time.Now()
366+
func (r *InhibitRule) hasEqual(lset model.LabelSet, excludeTwoSidedMatch bool, now time.Time) (model.Fingerprint, bool) {
365367
equal, found := r.findEqualSourceAlert(lset, now)
366368
if found {
367369
if excludeTwoSidedMatch && r.TargetMatchers.Matches(equal.Labels) {

inhibit/inhibit_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func TestInhibitRuleHasEqual(t *testing.T) {
138138
r.updateIndex(v)
139139
}
140140

141-
if _, have := r.hasEqual(c.input, false); have != c.result {
141+
if _, have := r.hasEqual(c.input, false, time.Now()); have != c.result {
142142
t.Errorf("Unexpected result %t, expected %t", have, c.result)
143143
}
144144
})

inhibit/metric.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type InhibitorMetrics struct {
2323
sourceAlertsCacheItems prometheus.Gauge
2424
sourceAlertsIndexItems prometheus.Gauge
2525
mutesDuration *prometheus.SummaryVec
26+
mutesDurationMuted prometheus.Observer
27+
mutesDurationNotMuted prometheus.Observer
2628

2729
// Rule metrics
2830
ruleSourceAlertsCacheItems *prometheus.GaugeVec
@@ -53,6 +55,7 @@ func NewInhibitorMetrics(reg prometheus.Registerer) *InhibitorMetrics {
5355
},
5456
[]string{"muted"},
5557
),
58+
5659
ruleSourceAlertsCacheItems: prometheus.NewGaugeVec(
5760
prometheus.GaugeOpts{
5861
Name: "alertmanager_inhibit_rule_source_alerts_cache_items",
@@ -82,6 +85,10 @@ func NewInhibitorMetrics(reg prometheus.Registerer) *InhibitorMetrics {
8285
[]string{"rule", "muted"},
8386
),
8487
}
88+
89+
metrics.mutesDurationMuted = metrics.mutesDuration.With(prometheus.Labels{"muted": "true"})
90+
metrics.mutesDurationNotMuted = metrics.mutesDuration.With(prometheus.Labels{"muted": "false"})
91+
8592
if reg != nil {
8693
reg.MustRegister(
8794
metrics.sourceAlertsCacheItems,
@@ -101,20 +108,26 @@ func NewInhibitorMetrics(reg prometheus.Registerer) *InhibitorMetrics {
101108
}
102109

103110
type RuleMetrics struct {
104-
ruleName string
105-
matchesDuration *prometheus.SummaryVec
106-
mutesDuration *prometheus.SummaryVec
111+
ruleName string
112+
matchesDurationMatched prometheus.Observer
113+
matchesDurationNotMatched prometheus.Observer
114+
115+
mutesDurationMuted prometheus.Observer
116+
mutesDurationNotMuted prometheus.Observer
117+
107118
sourceAlertsCacheItems *prometheus.GaugeVec
108119
sourceAlertsIndexItems *prometheus.GaugeVec
109120
}
110121

111122
func NewRuleMetrics(name string, metrics *InhibitorMetrics) *RuleMetrics {
112123
rm := &RuleMetrics{
113-
ruleName: name,
114-
matchesDuration: metrics.ruleMatchesDuration,
115-
mutesDuration: metrics.ruleMutesDuration,
116-
sourceAlertsCacheItems: metrics.ruleSourceAlertsCacheItems,
117-
sourceAlertsIndexItems: metrics.ruleSourceAlertsIndexItems,
124+
ruleName: name,
125+
matchesDurationMatched: metrics.ruleMatchesDuration.With(prometheus.Labels{"rule": name, "matched": "true"}),
126+
matchesDurationNotMatched: metrics.ruleMatchesDuration.With(prometheus.Labels{"rule": name, "matched": "false"}),
127+
mutesDurationMuted: metrics.ruleMutesDuration.With(prometheus.Labels{"rule": name, "muted": "true"}),
128+
mutesDurationNotMuted: metrics.ruleMutesDuration.With(prometheus.Labels{"rule": name, "muted": "false"}),
129+
sourceAlertsCacheItems: metrics.ruleSourceAlertsCacheItems,
130+
sourceAlertsIndexItems: metrics.ruleSourceAlertsIndexItems,
118131
}
119132

120133
rm.sourceAlertsCacheItems.With(prometheus.Labels{"rule": rm.ruleName}).Set(0)

0 commit comments

Comments
 (0)