-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdistributed_bench_test.go
99 lines (91 loc) · 2.65 KB
/
distributed_bench_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package ratelimit
import (
"context"
"fmt"
"math"
"strconv"
"strings"
"sync/atomic"
"time"
"testing"
"github.com/yesyoukenspace/go-ratelimit/internal/utils"
)
func BenchmarkDistributed(b *testing.B) {
rate := math.Pow10(4)
burst := int(math.Pow10(4))
ratelimiters := []struct {
name string
c func() Ratelimiter
}{
{name: "Redis", c: func() Ratelimiter { return NewGoRedis(newRDB(2), rate, burst) }},
{name: "Redis with delay in sync", c: func() Ratelimiter {
return NewRedisDelayedSync(context.Background(), RedisDelayedSyncOption{
RedisClient: newRDB(3),
TokenPerSec: rate,
Burst: burst,
SyncInterval: time.Second / 2,
})
},
},
}
for _, concurrentUsers := range []int{2048, 16384} {
for _, limiter := range ratelimiters {
benchmarkDistributed(b, benchmarkDistributedConfig{
name: limiter.name,
concurrentUsers: concurrentUsers,
burst: burst,
rate: rate,
constructor: limiter.c,
avgConcurrencyPerUser: 8,
numServers: 2,
})
}
}
}
type benchmarkDistributedConfig struct {
name string
concurrentUsers int
avgConcurrencyPerUser int
burst int
rate float64
constructor func() Ratelimiter
numServers int64
}
func benchmarkDistributed(b *testing.B, c benchmarkDistributedConfig) bool {
maxAllowed, maxDisallowed, maxLapsed := 0.0, 0.0, 0.0
name := strings.ReplaceAll(c.name, " ", "_")
runResult := b.Run(name, func(b *testing.B) {
b.ReportAllocs()
b.SetParallelism(c.concurrentUsers)
allowed := atomic.Int64{}
disallowed := atomic.Int64{}
rls := make([]Ratelimiter, 0, c.numServers)
for range c.numServers {
rls = append(rls, c.constructor())
}
b.RunParallel(func(pb *testing.PB) {
// To simulate different users hitting different rate limiters in a distributed system
rStr := strconv.FormatInt(utils.RandInt(0, int64(c.concurrentUsers/c.avgConcurrencyPerUser)), 10)
rl := rls[utils.RandInt(0, c.numServers)]
a := int64(0)
d := int64(0)
for pb.Next() {
if ok, _ := rl.Allow(rStr); ok {
a++
} else {
d++
}
}
allowed.Add(int64(a))
disallowed.Add(int64(d))
})
lapsed := b.Elapsed().Seconds()
if lapsed > maxLapsed {
maxLapsed = lapsed
maxAllowed = float64(allowed.Load())
maxDisallowed = float64(disallowed.Load())
}
})
fmt.Printf("%s/custom_metrics\tallowed=%f\tdisallowed=%f\tlapsed=%f\tallowed(rps)=%f\ttotal(rps)=%f\n", b.Name()+"/"+name, maxAllowed, maxDisallowed, maxLapsed, maxAllowed/maxLapsed, (maxAllowed+maxDisallowed)/maxLapsed)
return runResult
}