From a61765d58192a14be50af262c24fda413a595212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Fri, 1 Jul 2022 18:43:16 +0200 Subject: [PATCH] replace aggression with exponent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sandor Szücs --- docs/reference/filters.md | 21 +++++++++++---------- filters/shedder/admission.go | 24 ++++++++++++------------ filters/shedder/admission_test.go | 18 +++++++++--------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/docs/reference/filters.md b/docs/reference/filters.md index 3dd835fd60..b4a0ecf1e1 100644 --- a/docs/reference/filters.md +++ b/docs/reference/filters.md @@ -1860,16 +1860,17 @@ that explains the basic principles. ### admissionControl -Implements an admission control filter similar to [envoy admission control](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/admission_control_filter#admission-control). +Implements an admission control filter, that rejects traffic by +observed error rate and probability. The probability of rejection is calculated by the following equation: -$$ P_{reject} = ( { n_{total} - { n_{success} \over threshold } \over n_{total} + 1} )^{1 \over aggression } $$ +$$ P_{reject} = ( { n_{total} - { n_{success} \over threshold } \over n_{total} + 1} )^{ exponent } $$ Examples: admissionControl(metricSuffix, mode, d, windowSize, minRPS, successThreshold, maxRejectProbability, aggression) - admissionControl("myapp", "active", "1s", 5, 10, 0.95, 0.9, 2.0) + admissionControl("myapp", "active", "1s", 5, 10, 0.95, 0.9, 0.5) Parameters: @@ -1880,7 +1881,7 @@ Parameters: * min requests (int) * success threshold (float64) * max reject probability (float64) -* aggression (float64) +* exponent (float64) Metric suffix is the chosen suffix key to expose reject counter, should be unique by filter instance @@ -1910,14 +1911,14 @@ Max reject probability sets the upper bound of reject probability. It is within (0,1] and defaults to 0.95, which means if backend errors with 100% it will only reject up to 95%. -aggression is used to dictate the rejection probability. The -calculation is done by $p = p^{1 \over aggression}$ -The aggression value is within $(0,\infty]$: +exponent is used to dictate the rejection probability. The +calculation is done by $p = p^{exponent}$ +The exponent value is within $(0,\infty]$, to increase rejection +probability you have to use values lower than 1: * 1: linear (default) -* 2: quadratic -* 3: cubic -* see also [envoy aggression](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/admission_control_filter#aggression) +* 1/2: quadratic +* 1/3: cubic !!! This filter is experimental and defaults are likely to change diff --git a/filters/shedder/admission.go b/filters/shedder/admission.go index eca98eee47..80f2f176cf 100644 --- a/filters/shedder/admission.go +++ b/filters/shedder/admission.go @@ -91,7 +91,7 @@ const ( maxWindowSize = 100 defaultThreshold = float64(0.95) defaultMaxRejectProbability = float64(0.95) - defaultAggression = float64(1) + defaultExponent = float64(1) ) type Options struct { @@ -117,7 +117,7 @@ type admissionControl struct { d time.Duration successThreshold float64 // (0,1] maxRejectProbability float64 // (0,1] - aggression float64 // >0 + exponent float64 // >0 totals []int64 success []int64 @@ -139,8 +139,8 @@ func (*admissionControlSpec) Name() string { return filters.AdmissionControlName // CreateFilter creates a new admissionControl filter with passed configuration: // -// admissionControl(metricSuffix, mode, d, windowSize, minRPS, successThreshold, maxRejectProbability, aggression) -// admissionControl("$app", "active", "1s", 5, 10, 0.1, 0.95, 2.0) +// admissionControl(metricSuffix, mode, d, windowSize, minRPS, successThreshold, maxRejectProbability, exponent) +// admissionControl("$app", "active", "1s", 5, 10, 0.1, 0.95, 0.5) // // metricSuffix is the suffix key to expose reject counter, should be unique by filter instance // mode is one of "active", "inactive", "logInactive" @@ -151,7 +151,7 @@ func (*admissionControlSpec) Name() string { return filters.AdmissionControlName // minRPS // successThreshold is within (0,1] and sets the lowest request success rate at which the filter will not reject requests. // maxRejectProbability is within (0,1] and sets the upper bound of reject probability. -// aggression >= 1, 1: linear, 2: qudratic, .., see also https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/admission_control_filter#aggression +// exponent >0, 1: linear, 1/2: qudratic, 1/3: cubic, .. // // see also https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/admission_control_filter#admission-control func (spec *admissionControlSpec) CreateFilter(args []interface{}) (filters.Filter, error) { @@ -226,15 +226,15 @@ func (spec *admissionControlSpec) CreateFilter(args []interface{}) (filters.Filt } } - aggression := defaultAggression + exponent := defaultExponent if len(args) > 7 { - aggression, err = getFloat64Arg(args[7]) + exponent, err = getFloat64Arg(args[7]) if err != nil { - log.Warnf("aggression failed: %v", err) + log.Warnf("exponent failed: %v", err) return nil, filters.ErrInvalidFilterParameters } - if aggression <= 0.0 { - log.Warn("aggression should be >0") + if exponent <= 0.0 { + log.Warn("exponent should be >0") return nil, filters.ErrInvalidFilterParameters } } @@ -251,7 +251,7 @@ func (spec *admissionControlSpec) CreateFilter(args []interface{}) (filters.Filt minRequests: minRequests, successThreshold: threshold, maxRejectProbability: maxRejectProbability, - aggression: aggression, + exponent: exponent, totals: make([]int64, windowSize), success: make([]int64, windowSize), @@ -321,7 +321,7 @@ func (ac *admissionControl) pReject() float64 { return -1 } rejectP = (total - s) / (total + 1) - rejectP = math.Pow(rejectP, 1/ac.aggression) + rejectP = math.Pow(rejectP, ac.exponent) rejectP = math.Min(rejectP, ac.maxRejectProbability) return math.Max(rejectP, 0.0) diff --git a/filters/shedder/admission_test.go b/filters/shedder/admission_test.go index e7ab78052b..742aa2b3b8 100644 --- a/filters/shedder/admission_test.go +++ b/filters/shedder/admission_test.go @@ -23,7 +23,7 @@ func TestAdmissionControl(t *testing.T) { minRequests int successThreshold float64 maxrejectprobability float64 - aggression float64 + exponent float64 N float64 // iterations pBackendErr float64 // [0,1] pExpectedAdmissionShedding float64 // [0,1] @@ -35,7 +35,7 @@ func TestAdmissionControl(t *testing.T) { minRequests: 10, successThreshold: 0.9, maxrejectprobability: 0.95, - aggression: 1.0, + exponent: 1.0, N: 10000, pBackendErr: 0.0, pExpectedAdmissionShedding: 0.0, @@ -47,7 +47,7 @@ func TestAdmissionControl(t *testing.T) { minRequests: 10, successThreshold: 0.9, maxrejectprobability: 0.95, - aggression: 1.0, // 1000.0 + exponent: 1.0, // 1000.0 N: 10000, pBackendErr: 1.0, pExpectedAdmissionShedding: 0.95, @@ -59,7 +59,7 @@ func TestAdmissionControl(t *testing.T) { minRequests: 10, successThreshold: 0.9, maxrejectprobability: 0.95, - aggression: 1.0, + exponent: 1.0, N: 10000, pBackendErr: 0.01, pExpectedAdmissionShedding: 0.0, @@ -71,7 +71,7 @@ func TestAdmissionControl(t *testing.T) { minRequests: 10, successThreshold: 0.99, maxrejectprobability: 0.95, - aggression: 1.0, + exponent: 1.0, N: 10000, pBackendErr: 0.1, pExpectedAdmissionShedding: 0.1, @@ -83,7 +83,7 @@ func TestAdmissionControl(t *testing.T) { minRequests: 10, successThreshold: 0.9, maxrejectprobability: 0.95, - aggression: 1.0, + exponent: 1.0, N: 10000, pBackendErr: 0.2, pExpectedAdmissionShedding: 0.1, @@ -95,7 +95,7 @@ func TestAdmissionControl(t *testing.T) { minRequests: 10, successThreshold: 0.9, maxrejectprobability: 0.95, - aggression: 1.0, + exponent: 1.0, N: 10000, pBackendErr: 0.5, pExpectedAdmissionShedding: 0.615, @@ -107,7 +107,7 @@ func TestAdmissionControl(t *testing.T) { minRequests: 10, successThreshold: 0.9, maxrejectprobability: 0.95, - aggression: 1.0, + exponent: 1.0, N: 10000, pBackendErr: 0.8, pExpectedAdmissionShedding: 0.91, @@ -124,7 +124,7 @@ func TestAdmissionControl(t *testing.T) { spec := NewAdmissionControl(Options{}) args := make([]interface{}, 0, 6) - args = append(args, "testmetric", ti.mode, ti.d.String(), ti.windowsize, ti.minRequests, ti.successThreshold, ti.maxrejectprobability, ti.aggression) + args = append(args, "testmetric", ti.mode, ti.d.String(), ti.windowsize, ti.minRequests, ti.successThreshold, ti.maxrejectprobability, ti.exponent) _, err := spec.CreateFilter(args) if err != nil { t.Logf("args: %+v", args...)