github.com/thanos-io/thanos@v0.32.5/pkg/cache/groupcache_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package cache 5 6 import ( 7 "context" 8 "crypto/tls" 9 "fmt" 10 "net" 11 "net/http" 12 "os" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/go-kit/log" 18 "github.com/prometheus/client_golang/prometheus" 19 "github.com/prometheus/common/route" 20 "github.com/thanos-io/objstore" 21 galaxyhttp "github.com/vimeo/galaxycache/http" 22 "golang.org/x/net/http2" 23 24 "github.com/efficientgo/core/testutil" 25 "github.com/thanos-io/thanos/pkg/component" 26 "github.com/thanos-io/thanos/pkg/discovery/dns" 27 "github.com/thanos-io/thanos/pkg/model" 28 "github.com/thanos-io/thanos/pkg/prober" 29 httpserver "github.com/thanos-io/thanos/pkg/server/http" 30 "github.com/thanos-io/thanos/pkg/store/cache/cachekey" 31 ) 32 33 const basePath = `/_groupcache/` 34 const groupName = `groupName` 35 const selfURLH1 = "http://localhost:12345" 36 const selfURLH2C = "http://localhost:12346" 37 38 func TestMain(m *testing.M) { 39 reg := prometheus.NewRegistry() 40 router := route.New() 41 42 bkt := objstore.NewInMemBucket() 43 defer bkt.Close() 44 45 payload := strings.Repeat("foobar", 16*1024/6) 46 47 if err := bkt.Upload(context.Background(), "test", strings.NewReader(payload)); err != nil { 48 fmt.Printf("failed to upload: %s\n", err.Error()) 49 os.Exit(1) 50 } 51 52 httpServer := httpserver.New(log.NewNopLogger(), nil, component.Bucket, &prober.HTTPProbe{}, 53 httpserver.WithListen("0.0.0.0:12345")) 54 httpServer.Handle("/", router) 55 httpServerH2C := httpserver.New(log.NewNopLogger(), nil, component.Bucket, &prober.HTTPProbe{}, 56 httpserver.WithListen("0.0.0.0:12346"), httpserver.WithEnableH2C(true)) 57 httpServerH2C.Handle("/", router) 58 59 cachingBucketConfig := NewCachingBucketConfig() 60 cachingBucketConfig.CacheGet("test", nil, func(s string) bool { 61 return true 62 }, 16*1024, 0*time.Second, 0*time.Second, 0*time.Second) 63 64 groupCache, err := NewGroupcacheWithConfig( 65 log.NewJSONLogger(os.Stderr), 66 reg, 67 GroupcacheConfig{ 68 Peers: []string{selfURLH1}, 69 SelfURL: selfURLH1, 70 GroupcacheGroup: groupName, 71 DNSSDResolver: dns.MiekgdnsResolverType, 72 DNSInterval: 30 * time.Second, 73 MaxSize: model.Bytes(16 * 1024), 74 }, 75 basePath, 76 router, 77 bkt, 78 cachingBucketConfig, 79 ) 80 if err != nil { 81 fmt.Printf("failed creating group cache: %s\n", err.Error()) 82 os.Exit(1) 83 } 84 85 go func() { 86 if err = httpServer.ListenAndServe(); err != nil { 87 fmt.Printf("failed to listen: %s\n", err.Error()) 88 os.Exit(1) 89 } 90 }() 91 go func() { 92 if err = httpServerH2C.ListenAndServe(); err != nil { 93 fmt.Printf("failed to listen: %s\n", err.Error()) 94 os.Exit(1) 95 } 96 }() 97 98 defer httpServer.Shutdown(nil) 99 defer httpServerH2C.Shutdown(nil) 100 101 cachingBucketConfig.SetCacheImplementation(groupCache) 102 103 exitVal := m.Run() 104 105 os.Exit(exitVal) 106 } 107 108 // Benchmark retrieval of one key from one groupcache node. 109 func BenchmarkGroupcacheRetrieval(b *testing.B) { 110 b.Run("h2c", func(b *testing.B) { 111 fetcher := galaxyhttp.NewHTTPFetchProtocol(&galaxyhttp.HTTPOptions{ 112 Transport: &http2.Transport{ 113 AllowHTTP: true, 114 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 115 return net.Dial(network, addr) 116 }, 117 }, 118 BasePath: basePath, 119 }) 120 121 f, err := fetcher.NewFetcher(selfURLH2C) 122 testutil.Ok(b, err) 123 124 b.Run("seq", func(b *testing.B) { 125 b.ResetTimer() 126 b.ReportAllocs() 127 128 for i := 0; i < b.N; i++ { 129 _, _, err = f.Fetch(context.Background(), groupName, cachekey.BucketCacheKey{Verb: "content", Name: "test"}.String()) 130 testutil.Ok(b, err) 131 } 132 }) 133 b.Run("parallel=500", func(b *testing.B) { 134 b.ResetTimer() 135 b.ReportAllocs() 136 137 ch := make(chan struct{}) 138 139 for i := 0; i < 500; i++ { 140 go func() { 141 for range ch { 142 _, _, err = f.Fetch(context.Background(), groupName, cachekey.BucketCacheKey{Verb: "content", Name: "test"}.String()) 143 testutil.Ok(b, err) 144 } 145 }() 146 } 147 148 for i := 0; i < b.N; i++ { 149 ch <- struct{}{} 150 } 151 close(ch) 152 }) 153 }) 154 b.Run("h1, max one TCP connection", func(b *testing.B) { 155 fetcher := galaxyhttp.NewHTTPFetchProtocol(&galaxyhttp.HTTPOptions{ 156 BasePath: basePath, 157 Transport: &http.Transport{ 158 MaxConnsPerHost: 1, 159 MaxIdleConnsPerHost: 1, 160 }, 161 }) 162 163 f, err := fetcher.NewFetcher(selfURLH1) 164 testutil.Ok(b, err) 165 166 b.Run("seq", func(b *testing.B) { 167 b.ResetTimer() 168 b.ReportAllocs() 169 170 for i := 0; i < b.N; i++ { 171 _, _, err = f.Fetch(context.Background(), groupName, cachekey.BucketCacheKey{Verb: "content", Name: "test"}.String()) 172 testutil.Ok(b, err) 173 } 174 }) 175 176 b.Run("parallel=500", func(b *testing.B) { 177 b.ResetTimer() 178 b.ReportAllocs() 179 180 ch := make(chan struct{}) 181 182 for i := 0; i < 500; i++ { 183 go func() { 184 for range ch { 185 _, _, err = f.Fetch(context.Background(), groupName, cachekey.BucketCacheKey{Verb: "content", Name: "test"}.String()) 186 testutil.Ok(b, err) 187 } 188 }() 189 } 190 191 for i := 0; i < b.N; i++ { 192 ch <- struct{}{} 193 } 194 close(ch) 195 }) 196 }) 197 b.Run("h1, unlimited TCP connections", func(b *testing.B) { 198 fetcher := galaxyhttp.NewHTTPFetchProtocol(&galaxyhttp.HTTPOptions{ 199 BasePath: basePath, 200 Transport: &http.Transport{}, 201 }) 202 203 f, err := fetcher.NewFetcher(selfURLH1) 204 testutil.Ok(b, err) 205 206 b.Run("seq", func(b *testing.B) { 207 b.ResetTimer() 208 b.ReportAllocs() 209 210 for i := 0; i < b.N; i++ { 211 _, _, err = f.Fetch(context.Background(), groupName, cachekey.BucketCacheKey{Verb: "content", Name: "test"}.String()) 212 testutil.Ok(b, err) 213 } 214 }) 215 216 b.Run("parallel=500", func(b *testing.B) { 217 b.ResetTimer() 218 b.ReportAllocs() 219 220 ch := make(chan struct{}) 221 222 for i := 0; i < 500; i++ { 223 go func() { 224 for range ch { 225 _, _, err = f.Fetch(context.Background(), groupName, cachekey.BucketCacheKey{Verb: "content", Name: "test"}.String()) 226 testutil.Ok(b, err) 227 } 228 }() 229 } 230 231 for i := 0; i < b.N; i++ { 232 ch <- struct{}{} 233 } 234 close(ch) 235 }) 236 }) 237 238 }