6
6
"fmt"
7
7
"io"
8
8
"math"
9
+ "math/rand"
9
10
"net/http"
10
11
"sort"
11
12
"strconv"
@@ -1654,6 +1655,56 @@ func TestDistributor_Push_ExemplarValidation(t *testing.T) {
1654
1655
}
1655
1656
}
1656
1657
1658
+ func BenchmarkDistributor_GetLabelsValues (b * testing.B ) {
1659
+ ctx := user .InjectOrgID (context .Background (), "user" )
1660
+
1661
+ testCases := []struct {
1662
+ numIngesters int
1663
+ lblValuesPerIngester int
1664
+ lblValuesDuplicateRatio float64
1665
+ }{
1666
+ {
1667
+ numIngesters : 150 ,
1668
+ lblValuesPerIngester : 1000 ,
1669
+ lblValuesDuplicateRatio : 0.67 , // Final Result will have 33% of the total size - replication factor of 3 and no duplicates
1670
+ },
1671
+ {
1672
+ numIngesters : 150 ,
1673
+ lblValuesPerIngester : 1000 ,
1674
+ lblValuesDuplicateRatio : 0.98 ,
1675
+ },
1676
+ {
1677
+ numIngesters : 500 ,
1678
+ lblValuesPerIngester : 1000 ,
1679
+ lblValuesDuplicateRatio : 0.67 , // Final Result will have 33% of the total size - replication factor of 3 and no duplicates
1680
+ },
1681
+ {
1682
+ numIngesters : 500 ,
1683
+ lblValuesPerIngester : 1000 ,
1684
+ lblValuesDuplicateRatio : 0.98 ,
1685
+ },
1686
+ }
1687
+
1688
+ for _ , tc := range testCases {
1689
+ name := fmt .Sprintf ("numIngesters%v,lblValuesPerIngester%v,lblValuesDuplicateRatio%v" , tc .numIngesters , tc .lblValuesPerIngester , tc .lblValuesDuplicateRatio )
1690
+ ds , _ , _ , _ := prepare (b , prepConfig {
1691
+ numIngesters : tc .numIngesters ,
1692
+ happyIngesters : tc .numIngesters ,
1693
+ numDistributors : 1 ,
1694
+ lblValuesPerIngester : tc .lblValuesPerIngester ,
1695
+ lblValuesDuplicateRatio : tc .lblValuesDuplicateRatio ,
1696
+ })
1697
+ b .Run (name , func (b * testing.B ) {
1698
+ b .ResetTimer ()
1699
+ b .ReportAllocs ()
1700
+ for i := 0 ; i < b .N ; i ++ {
1701
+ _ , err := ds [0 ].LabelValuesForLabelName (ctx , model .Time (time .Now ().UnixMilli ()), model .Time (time .Now ().UnixMilli ()), "__name__" )
1702
+ require .NoError (b , err )
1703
+ }
1704
+ })
1705
+ }
1706
+ }
1707
+
1657
1708
func BenchmarkDistributor_Push (b * testing.B ) {
1658
1709
const (
1659
1710
numSeriesPerRequest = 1000
@@ -1942,7 +1993,6 @@ func BenchmarkDistributor_Push(b *testing.B) {
1942
1993
1943
1994
for n := 0 ; n < b .N ; n ++ {
1944
1995
_ , err := distributor .Push (ctx , cortexpb .ToWriteRequest (metrics , samples , nil , nil , cortexpb .API ))
1945
-
1946
1996
if testData .expectedErr == "" && err != nil {
1947
1997
b .Fatalf ("no error expected but got %v" , err )
1948
1998
}
@@ -2392,6 +2442,8 @@ type prepConfig struct {
2392
2442
shardByAllLabels bool
2393
2443
shuffleShardEnabled bool
2394
2444
shuffleShardSize int
2445
+ lblValuesPerIngester int
2446
+ lblValuesDuplicateRatio float64
2395
2447
limits * validation.Limits
2396
2448
numDistributors int
2397
2449
skipLabelNameValidation bool
@@ -2403,13 +2455,23 @@ type prepConfig struct {
2403
2455
tokens [][]uint32
2404
2456
}
2405
2457
2458
+ type prepState struct {
2459
+ unusedStrings , usedStrings []string
2460
+ }
2461
+
2406
2462
func prepare (tb testing.TB , cfg prepConfig ) ([]* Distributor , []* mockIngester , []* prometheus.Registry , * ring.Ring ) {
2463
+ // Strings to be used for get labels values/Names
2464
+ var unusedStrings []string
2465
+ if cfg .lblValuesPerIngester > 0 {
2466
+ unusedStrings = make ([]string , min (len (util .RandomStrings ), cfg .numIngesters * cfg .lblValuesPerIngester ))
2467
+ copy (unusedStrings , util .RandomStrings )
2468
+ }
2469
+ s := & prepState {
2470
+ unusedStrings : unusedStrings ,
2471
+ }
2407
2472
ingesters := []* mockIngester {}
2408
2473
for i := 0 ; i < cfg .happyIngesters ; i ++ {
2409
- ingesters = append (ingesters , & mockIngester {
2410
- happy : * atomic .NewBool (true ),
2411
- queryDelay : cfg .queryDelay ,
2412
- })
2474
+ ingesters = append (ingesters , newMockIngester (i , s , cfg ))
2413
2475
}
2414
2476
for i := cfg .happyIngesters ; i < cfg .numIngesters ; i ++ {
2415
2477
miError := errFail
@@ -2679,6 +2741,33 @@ type mockIngester struct {
2679
2741
metadata map [uint32 ]map [cortexpb.MetricMetadata ]struct {}
2680
2742
queryDelay time.Duration
2681
2743
calls map [string ]int
2744
+ lblsValues []string
2745
+ }
2746
+
2747
+ func newMockIngester (id int , ps * prepState , cfg prepConfig ) * mockIngester {
2748
+ lblsValues := make ([]string , 0 , cfg .lblValuesPerIngester )
2749
+ usedStrings := make ([]string , len (ps .usedStrings ))
2750
+ copy (usedStrings , ps .usedStrings )
2751
+
2752
+ for i := 0 ; i < cfg .lblValuesPerIngester ; i ++ {
2753
+ var s string
2754
+ if i < int (float64 (cfg .lblValuesPerIngester )* cfg .lblValuesDuplicateRatio ) && id > 0 {
2755
+ index := rand .Int () % len (usedStrings )
2756
+ s = usedStrings [index ]
2757
+ usedStrings = append (usedStrings [:index ], usedStrings [index + 1 :]... )
2758
+ } else {
2759
+ s = ps .unusedStrings [0 ]
2760
+ ps .usedStrings = append (ps .usedStrings , s )
2761
+ ps .unusedStrings = ps .unusedStrings [1 :]
2762
+ }
2763
+ lblsValues = append (lblsValues , s )
2764
+ }
2765
+ sort .Strings (lblsValues )
2766
+ return & mockIngester {
2767
+ happy : * atomic .NewBool (true ),
2768
+ queryDelay : cfg .queryDelay ,
2769
+ lblsValues : lblsValues ,
2770
+ }
2682
2771
}
2683
2772
2684
2773
func (i * mockIngester ) series () map [uint32 ]* cortexpb.PreallocTimeseries {
@@ -2705,6 +2794,12 @@ func (i *mockIngester) Close() error {
2705
2794
return nil
2706
2795
}
2707
2796
2797
+ func (i * mockIngester ) LabelValues (_ context.Context , _ * client.LabelValuesRequest , _ ... grpc.CallOption ) (* client.LabelValuesResponse , error ) {
2798
+ return & client.LabelValuesResponse {
2799
+ LabelValues : i .lblsValues ,
2800
+ }, nil
2801
+ }
2802
+
2708
2803
func (i * mockIngester ) PushPreAlloc (ctx context.Context , in * cortexpb.PreallocWriteRequest , opts ... grpc.CallOption ) (* cortexpb.WriteResponse , error ) {
2709
2804
return i .Push (ctx , & in .WriteRequest , opts ... )
2710
2805
}
0 commit comments