Merge pull request #85152 from mikedanese/tokbench
report cache misses in cached token authenticator benchmark Kubernetes-commit: 570572b38773829e2841033967f7f7364f56206e
This commit is contained in:
commit
5ec070f50a
|
@ -26,6 +26,7 @@ import (
|
||||||
mathrand "math/rand"
|
mathrand "math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -194,6 +195,11 @@ func newSingleBenchmark(tokens, threads int) *singleBenchmark {
|
||||||
// singleBenchmark collects all the state needed to run a benchmark. The
|
// singleBenchmark collects all the state needed to run a benchmark. The
|
||||||
// question this benchmark answers is, "what's the average latency added by the
|
// question this benchmark answers is, "what's the average latency added by the
|
||||||
// cache for N concurrent tokens?"
|
// cache for N concurrent tokens?"
|
||||||
|
//
|
||||||
|
// Given the size of the key range constructed by this test, the default go
|
||||||
|
// benchtime of 1 second is often inadequate to test caching and expiration
|
||||||
|
// behavior. A benchtime of 10 to 30 seconds is adequate to stress these
|
||||||
|
// code paths.
|
||||||
type singleBenchmark struct {
|
type singleBenchmark struct {
|
||||||
threadCount int
|
threadCount int
|
||||||
// These token.* variables are set by makeTokens()
|
// These token.* variables are set by makeTokens()
|
||||||
|
@ -204,11 +210,6 @@ type singleBenchmark struct {
|
||||||
tokenToAuds map[string]authenticator.Audiences
|
tokenToAuds map[string]authenticator.Audiences
|
||||||
// a list makes it easy to select a random one
|
// a list makes it easy to select a random one
|
||||||
tokens []string
|
tokens []string
|
||||||
|
|
||||||
// Simulate slowness, qps limit, external service limitation, etc
|
|
||||||
chokepoint chan struct{}
|
|
||||||
|
|
||||||
b *testing.B
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *singleBenchmark) makeTokens() {
|
func (s *singleBenchmark) makeTokens() {
|
||||||
|
@ -228,12 +229,12 @@ func (s *singleBenchmark) makeTokens() {
|
||||||
for i := 0; i < mathrand.Intn(4); i++ {
|
for i := 0; i < mathrand.Intn(4); i++ {
|
||||||
auds = append(auds, string(uuid.NewUUID()))
|
auds = append(auds, string(uuid.NewUUID()))
|
||||||
}
|
}
|
||||||
choice := mathrand.Intn(1000)
|
choice := mathrand.Float64()
|
||||||
switch {
|
switch {
|
||||||
case choice < 900:
|
case choice < 0.9:
|
||||||
r.ok = true
|
r.ok = true
|
||||||
r.err = nil
|
r.err = nil
|
||||||
case choice < 990:
|
case choice < 0.99:
|
||||||
r.ok = false
|
r.ok = false
|
||||||
r.err = nil
|
r.err = nil
|
||||||
default:
|
default:
|
||||||
|
@ -249,9 +250,6 @@ func (s *singleBenchmark) makeTokens() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *singleBenchmark) lookup(ctx context.Context, token string) (*authenticator.Response, bool, error) {
|
func (s *singleBenchmark) lookup(ctx context.Context, token string) (*authenticator.Response, bool, error) {
|
||||||
s.chokepoint <- struct{}{}
|
|
||||||
defer func() { <-s.chokepoint }()
|
|
||||||
time.Sleep(1 * time.Millisecond)
|
|
||||||
r, ok := s.tokenToResponse[token]
|
r, ok := s.tokenToResponse[token]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("test setup problem")
|
panic("test setup problem")
|
||||||
|
@ -272,29 +270,41 @@ func (s *singleBenchmark) run(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *singleBenchmark) bench(b *testing.B) {
|
func (s *singleBenchmark) bench(b *testing.B) {
|
||||||
s.b = b
|
// Simulate slowness, qps limit, external service limitation, etc
|
||||||
|
const maxInFlight = 40
|
||||||
|
chokepoint := make(chan struct{}, maxInFlight)
|
||||||
|
// lookup count
|
||||||
|
var lookups uint64
|
||||||
|
|
||||||
a := newWithClock(
|
a := newWithClock(
|
||||||
authenticator.TokenFunc(s.lookup),
|
authenticator.TokenFunc(func(ctx context.Context, token string) (*authenticator.Response, bool, error) {
|
||||||
|
atomic.AddUint64(&lookups, 1)
|
||||||
|
|
||||||
|
chokepoint <- struct{}{}
|
||||||
|
defer func() { <-chokepoint }()
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
|
||||||
|
return s.lookup(ctx, token)
|
||||||
|
}),
|
||||||
true,
|
true,
|
||||||
4*time.Second,
|
4*time.Second,
|
||||||
500*time.Millisecond,
|
500*time.Millisecond,
|
||||||
utilclock.RealClock{},
|
utilclock.RealClock{},
|
||||||
)
|
)
|
||||||
const maxInFlight = 40
|
|
||||||
s.chokepoint = make(chan struct{}, maxInFlight)
|
|
||||||
|
|
||||||
s.b.ResetTimer()
|
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
b.SetParallelism(s.threadCount)
|
b.SetParallelism(s.threadCount)
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
r := mathrand.New(mathrand.NewSource(mathrand.Int63()))
|
r := mathrand.New(mathrand.NewSource(mathrand.Int63()))
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
// some problems appear with random
|
// some problems appear with random access, some appear with many
|
||||||
// access, some appear with many
|
// requests for a single entry, so we do both.
|
||||||
// requests for a single entry, so we
|
s.doAuthForTokenN(r.Intn(s.tokenCount), a)
|
||||||
// do both.
|
|
||||||
s.doAuthForTokenN(r.Intn(len(s.tokens)), a)
|
|
||||||
s.doAuthForTokenN(0, a)
|
s.doAuthForTokenN(0, a)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
b.StopTimer()
|
||||||
|
|
||||||
|
b.ReportMetric(float64(lookups)/float64(b.N), "lookups/op")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue