@@ -4,19 +4,21 @@ import (
4
4
"bytes"
5
5
"context"
6
6
"fmt"
7
- "strconv"
8
- "strings"
9
- "testing"
10
-
11
7
"github.com/efficientgo/core/testutil"
12
8
"github.com/go-kit/log"
13
9
"github.com/oklog/ulid"
14
10
"github.com/prometheus/client_golang/prometheus"
15
11
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
16
12
"github.com/prometheus/prometheus/model/labels"
17
13
"github.com/prometheus/prometheus/storage"
14
+ "github.com/stretchr/testify/require"
18
15
storecache "github.com/thanos-io/thanos/pkg/store/cache"
19
16
"github.com/thanos-io/thanos/pkg/tenancy"
17
+ "math/rand"
18
+ "strconv"
19
+ "strings"
20
+ "testing"
21
+ "time"
20
22
)
21
23
22
24
func TestInMemoryIndexCache_UpdateItem (t * testing.T ) {
@@ -139,3 +141,275 @@ func TestInMemoryIndexCacheSetOverflow(t *testing.T) {
139
141
cache .StoreSeries (id , 2 , []byte (sb .String ()), tenancy .DefaultTenant )
140
142
testutil .Equals (t , float64 (1 ), prom_testutil .ToFloat64 (counter ))
141
143
}
144
+
145
+ func BenchmarkInMemoryIndexCacheStore (b * testing.B ) {
146
+ logger := log .NewNopLogger ()
147
+ cfg := InMemoryIndexCacheConfig {
148
+ MaxSizeBytes : uint64 (storecache .DefaultInMemoryIndexCacheConfig .MaxSize ),
149
+ }
150
+
151
+ blockID := ulid .MustNew (ulid .Now (), nil )
152
+ r := rand .New (rand .NewSource (time .Now ().Unix ()))
153
+ // 1KB is a common size for series
154
+ seriesData := make ([]byte , 1024 )
155
+ r .Read (seriesData )
156
+ // 10MB might happen for large postings.
157
+ postingData := make ([]byte , 10 * 1024 * 1024 )
158
+ r .Read (postingData )
159
+
160
+ b .Run ("FastCache" , func (b * testing.B ) {
161
+ cache , err := newInMemoryIndexCache (cfg , logger , prometheus .NewRegistry ())
162
+ require .NoError (b , err )
163
+ b .ReportAllocs ()
164
+ b .ResetTimer ()
165
+ for i := 0 ; i < b .N ; i ++ {
166
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), seriesData , tenancy .DefaultTenant )
167
+ }
168
+ })
169
+
170
+ b .Run ("ThanosCache" , func (b * testing.B ) {
171
+ cache , err := storecache .NewInMemoryIndexCacheWithConfig (logger , nil , prometheus .NewRegistry (), storecache .DefaultInMemoryIndexCacheConfig )
172
+ require .NoError (b , err )
173
+ b .ReportAllocs ()
174
+ b .ResetTimer ()
175
+ for i := 0 ; i < b .N ; i ++ {
176
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), seriesData , tenancy .DefaultTenant )
177
+ }
178
+ })
179
+
180
+ b .Run ("FastCacheLargeItem" , func (b * testing.B ) {
181
+ cache , err := newInMemoryIndexCache (cfg , logger , prometheus .NewRegistry ())
182
+ require .NoError (b , err )
183
+ b .ReportAllocs ()
184
+ b .ResetTimer ()
185
+ for i := 0 ; i < b .N ; i ++ {
186
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), postingData , tenancy .DefaultTenant )
187
+ }
188
+ })
189
+
190
+ b .Run ("ThanosCacheLargeItem" , func (b * testing.B ) {
191
+ cache , err := storecache .NewInMemoryIndexCacheWithConfig (logger , nil , prometheus .NewRegistry (), storecache .DefaultInMemoryIndexCacheConfig )
192
+ require .NoError (b , err )
193
+ b .ReportAllocs ()
194
+ b .ResetTimer ()
195
+ for i := 0 ; i < b .N ; i ++ {
196
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), postingData , tenancy .DefaultTenant )
197
+ }
198
+ })
199
+ }
200
+
201
+ func BenchmarkInMemoryIndexCacheStoreConcurrent (b * testing.B ) {
202
+ logger := log .NewNopLogger ()
203
+ cfg := InMemoryIndexCacheConfig {
204
+ MaxSizeBytes : uint64 (storecache .DefaultInMemoryIndexCacheConfig .MaxSize ),
205
+ }
206
+
207
+ blockID := ulid .MustNew (ulid .Now (), nil )
208
+ r := rand .New (rand .NewSource (time .Now ().Unix ()))
209
+ // 1KB is a common size for series
210
+ seriesData := make ([]byte , 1024 )
211
+ r .Read (seriesData )
212
+ // 10MB might happen for large postings.
213
+ postingData := make ([]byte , 10 * 1024 * 1024 )
214
+ r .Read (postingData )
215
+
216
+ b .Run ("FastCache" , func (b * testing.B ) {
217
+ cache , err := newInMemoryIndexCache (cfg , logger , prometheus .NewRegistry ())
218
+ require .NoError (b , err )
219
+ ch := make (chan int )
220
+ b .ReportAllocs ()
221
+ b .ResetTimer ()
222
+
223
+ for i := 0 ; i < 500 ; i ++ {
224
+ go func () {
225
+ for j := range ch {
226
+ cache .StoreSeries (blockID , storage .SeriesRef (j ), seriesData , tenancy .DefaultTenant )
227
+ testutil .Ok (b , err )
228
+ }
229
+ }()
230
+ }
231
+
232
+ for i := 0 ; i < b .N ; i ++ {
233
+ ch <- i
234
+ }
235
+ close (ch )
236
+ })
237
+
238
+ b .Run ("ThanosCache" , func (b * testing.B ) {
239
+ cache , err := storecache .NewInMemoryIndexCacheWithConfig (logger , nil , prometheus .NewRegistry (), storecache .DefaultInMemoryIndexCacheConfig )
240
+ require .NoError (b , err )
241
+ ch := make (chan int )
242
+ b .ReportAllocs ()
243
+ b .ResetTimer ()
244
+
245
+ for i := 0 ; i < 500 ; i ++ {
246
+ go func () {
247
+ for j := range ch {
248
+ cache .StoreSeries (blockID , storage .SeriesRef (j ), seriesData , tenancy .DefaultTenant )
249
+ testutil .Ok (b , err )
250
+ }
251
+ }()
252
+ }
253
+
254
+ for i := 0 ; i < b .N ; i ++ {
255
+ ch <- i
256
+ }
257
+ close (ch )
258
+ })
259
+
260
+ b .Run ("FastCacheLargeItem" , func (b * testing.B ) {
261
+ cache , err := newInMemoryIndexCache (cfg , logger , prometheus .NewRegistry ())
262
+ require .NoError (b , err )
263
+ ch := make (chan int )
264
+ b .ReportAllocs ()
265
+ b .ResetTimer ()
266
+
267
+ for i := 0 ; i < 500 ; i ++ {
268
+ go func () {
269
+ for j := range ch {
270
+ cache .StoreSeries (blockID , storage .SeriesRef (j ), postingData , tenancy .DefaultTenant )
271
+ testutil .Ok (b , err )
272
+ }
273
+ }()
274
+ }
275
+
276
+ for i := 0 ; i < b .N ; i ++ {
277
+ ch <- i
278
+ }
279
+ close (ch )
280
+ })
281
+
282
+ b .Run ("ThanosCacheLargeItem" , func (b * testing.B ) {
283
+ cache , err := storecache .NewInMemoryIndexCacheWithConfig (logger , nil , prometheus .NewRegistry (), storecache .DefaultInMemoryIndexCacheConfig )
284
+ require .NoError (b , err )
285
+ ch := make (chan int )
286
+ b .ReportAllocs ()
287
+ b .ResetTimer ()
288
+
289
+ for i := 0 ; i < 500 ; i ++ {
290
+ go func () {
291
+ for j := range ch {
292
+ cache .StoreSeries (blockID , storage .SeriesRef (j ), postingData , tenancy .DefaultTenant )
293
+ testutil .Ok (b , err )
294
+ }
295
+ }()
296
+ }
297
+
298
+ for i := 0 ; i < b .N ; i ++ {
299
+ ch <- i
300
+ }
301
+ close (ch )
302
+ })
303
+ }
304
+
305
+ func BenchmarkInMemoryIndexCacheFetch (b * testing.B ) {
306
+ logger := log .NewNopLogger ()
307
+ cfg := InMemoryIndexCacheConfig {
308
+ MaxSizeBytes : uint64 (storecache .DefaultInMemoryIndexCacheConfig .MaxSize ),
309
+ }
310
+
311
+ blockID := ulid .MustNew (ulid .Now (), nil )
312
+ r := rand .New (rand .NewSource (time .Now ().Unix ()))
313
+ // 1KB is a common size for series
314
+ seriesData := make ([]byte , 1024 )
315
+ r .Read (seriesData )
316
+ ctx := context .Background ()
317
+ items := 10000
318
+ ids := make ([]storage.SeriesRef , items )
319
+ for i := 0 ; i < items ; i ++ {
320
+ ids [i ] = storage .SeriesRef (i )
321
+ }
322
+
323
+ b .Run ("FastCache" , func (b * testing.B ) {
324
+ cache , err := newInMemoryIndexCache (cfg , logger , prometheus .NewRegistry ())
325
+ require .NoError (b , err )
326
+ for i := 0 ; i < items ; i ++ {
327
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), seriesData , tenancy .DefaultTenant )
328
+ }
329
+ b .ReportAllocs ()
330
+ b .ResetTimer ()
331
+ for i := 0 ; i < b .N ; i ++ {
332
+ cache .FetchMultiSeries (ctx , blockID , ids , tenancy .DefaultTenant )
333
+ }
334
+ })
335
+
336
+ b .Run ("ThanosCache" , func (b * testing.B ) {
337
+ cache , err := storecache .NewInMemoryIndexCacheWithConfig (logger , nil , prometheus .NewRegistry (), storecache .DefaultInMemoryIndexCacheConfig )
338
+ require .NoError (b , err )
339
+ for i := 0 ; i < items ; i ++ {
340
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), seriesData , tenancy .DefaultTenant )
341
+ }
342
+ b .ReportAllocs ()
343
+ b .ResetTimer ()
344
+ for i := 0 ; i < b .N ; i ++ {
345
+ cache .FetchMultiSeries (ctx , blockID , ids , tenancy .DefaultTenant )
346
+ }
347
+ })
348
+ }
349
+
350
+ func BenchmarkInMemoryIndexCacheFetchConcurrent (b * testing.B ) {
351
+ logger := log .NewNopLogger ()
352
+ cfg := InMemoryIndexCacheConfig {
353
+ MaxSizeBytes : uint64 (storecache .DefaultInMemoryIndexCacheConfig .MaxSize ),
354
+ }
355
+
356
+ blockID := ulid .MustNew (ulid .Now (), nil )
357
+ r := rand .New (rand .NewSource (time .Now ().Unix ()))
358
+ // 1KB is a common size for series
359
+ seriesData := make ([]byte , 1024 )
360
+ r .Read (seriesData )
361
+ ctx := context .Background ()
362
+ items := 10000
363
+ ids := make ([]storage.SeriesRef , items )
364
+ for i := 0 ; i < items ; i ++ {
365
+ ids [i ] = storage .SeriesRef (i )
366
+ }
367
+
368
+ b .Run ("FastCache" , func (b * testing.B ) {
369
+ cache , err := newInMemoryIndexCache (cfg , logger , prometheus .NewRegistry ())
370
+ require .NoError (b , err )
371
+ for i := 0 ; i < items ; i ++ {
372
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), seriesData , tenancy .DefaultTenant )
373
+ }
374
+ b .ReportAllocs ()
375
+ b .ResetTimer ()
376
+
377
+ ch := make (chan int )
378
+ for i := 0 ; i < 500 ; i ++ {
379
+ go func () {
380
+ for range ch {
381
+ cache .FetchMultiSeries (ctx , blockID , ids , tenancy .DefaultTenant )
382
+ }
383
+ }()
384
+ }
385
+
386
+ for i := 0 ; i < b .N ; i ++ {
387
+ ch <- i
388
+ }
389
+ close (ch )
390
+ })
391
+
392
+ b .Run ("ThanosCache" , func (b * testing.B ) {
393
+ cache , err := storecache .NewInMemoryIndexCacheWithConfig (logger , nil , prometheus .NewRegistry (), storecache .DefaultInMemoryIndexCacheConfig )
394
+ require .NoError (b , err )
395
+ for i := 0 ; i < items ; i ++ {
396
+ cache .StoreSeries (blockID , storage .SeriesRef (i ), seriesData , tenancy .DefaultTenant )
397
+ }
398
+ b .ReportAllocs ()
399
+ b .ResetTimer ()
400
+
401
+ ch := make (chan int )
402
+ for i := 0 ; i < 500 ; i ++ {
403
+ go func () {
404
+ for range ch {
405
+ cache .FetchMultiSeries (ctx , blockID , ids , tenancy .DefaultTenant )
406
+ }
407
+ }()
408
+ }
409
+
410
+ for i := 0 ; i < b .N ; i ++ {
411
+ ch <- i
412
+ }
413
+ close (ch )
414
+ })
415
+ }
0 commit comments