Skip to content

Commit

Permalink
replace aggression with exponent
Browse files Browse the repository at this point in the history
Signed-off-by: Sandor Szücs <sandor.szuecs@zalando.de>
  • Loading branch information
szuecs committed Jul 1, 2022
1 parent 1f39aac commit a61765d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 31 deletions.
21 changes: 11 additions & 10 deletions docs/reference/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down
24 changes: 12 additions & 12 deletions filters/shedder/admission.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const (
maxWindowSize = 100
defaultThreshold = float64(0.95)
defaultMaxRejectProbability = float64(0.95)
defaultAggression = float64(1)
defaultExponent = float64(1)
)

type Options struct {
Expand All @@ -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
Expand All @@ -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"
Expand All @@ -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) {
Expand Down Expand Up @@ -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
}
}
Expand All @@ -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),
Expand Down Expand Up @@ -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)
Expand Down
18 changes: 9 additions & 9 deletions filters/shedder/admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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...)
Expand Down

0 comments on commit a61765d

Please sign in to comment.