6
6
"math/rand"
7
7
"net/url"
8
8
"sort"
9
+ "strconv"
9
10
"strings"
10
11
"sync"
11
12
"sync/atomic"
@@ -139,9 +140,10 @@ type Store interface {
139
140
140
141
// StoreConfig specifies config for a ChunkStore
141
142
type StoreConfig struct {
142
- S3URL string
143
- DynamoDBURL string
144
- ChunkCache * Cache
143
+ S3URL string
144
+ DynamoDBURL string
145
+ ChunkCache * Cache
146
+ DailyBucketsFrom model.Time
145
147
146
148
// Not exported as only used by tests to inject mocks
147
149
dynamodb dynamodbClient
@@ -206,6 +208,10 @@ type AWSStore struct {
206
208
tableName string
207
209
bucketName string
208
210
211
+ // Around which time to start bucketing indexes by day instead of by hour.
212
+ // Only the day matters, not the time within the day.
213
+ dailyBucketsFrom model.Time
214
+
209
215
dynamoRequests chan dynamoOp
210
216
dynamoRequestsDone sync.WaitGroup
211
217
}
@@ -332,25 +338,45 @@ func (c *AWSStore) CreateTables() error {
332
338
return err
333
339
}
334
340
335
- func bigBuckets (from , through model.Time ) []int64 {
341
+ func ( c * AWSStore ) bigBuckets (from , through model.Time ) []string {
336
342
var (
337
343
secondsInHour = int64 (time .Hour / time .Second )
338
344
fromHour = from .Unix () / secondsInHour
339
345
throughHour = through .Unix () / secondsInHour
340
- result []int64
346
+
347
+ secondsInDay = int64 (24 * time .Hour / time .Second )
348
+ fromDay = from .Unix () / secondsInDay
349
+ throughDay = through .Unix () / secondsInDay
350
+
351
+ firstDailyBucket = c .dailyBucketsFrom .Unix () / secondsInDay
352
+ lastHourlyBucket = firstDailyBucket * 24
353
+
354
+ result []string
341
355
)
356
+
342
357
for i := fromHour ; i <= throughHour ; i ++ {
343
- result = append (result , i )
358
+ if i > lastHourlyBucket {
359
+ break
360
+ }
361
+ result = append (result , strconv .Itoa (int (i )))
344
362
}
363
+
364
+ for i := fromDay ; i <= throughDay ; i ++ {
365
+ if i < firstDailyBucket {
366
+ continue
367
+ }
368
+ result = append (result , fmt .Sprintf ("d%d" , int (i )))
369
+ }
370
+
345
371
return result
346
372
}
347
373
348
374
func chunkName (userID , chunkID string ) string {
349
375
return fmt .Sprintf ("%s/%s" , userID , chunkID )
350
376
}
351
377
352
- func hashValue (userID string , hour int64 , metricName model.LabelValue ) string {
353
- return fmt .Sprintf ("%s:%d :%s" , userID , hour , metricName )
378
+ func hashValue (userID string , bucket string , metricName model.LabelValue ) string {
379
+ return fmt .Sprintf ("%s:%s :%s" , userID , bucket , metricName )
354
380
}
355
381
356
382
func rangeValue (label model.LabelName , value model.LabelValue , chunkID string ) []byte {
@@ -456,8 +482,8 @@ func (c *AWSStore) calculateDynamoWrites(userID string, chunks []Chunk) ([]*dyna
456
482
}
457
483
458
484
entries := 0
459
- for _ , hour := range bigBuckets (chunk .From , chunk .Through ) {
460
- hashValue := hashValue (userID , hour , metricName )
485
+ for _ , bucket := range c . bigBuckets (chunk .From , chunk .Through ) {
486
+ hashValue := hashValue (userID , bucket , metricName )
461
487
for label , value := range chunk .Metric {
462
488
if label == model .MetricNameLabel {
463
489
continue
@@ -542,18 +568,18 @@ func (c *AWSStore) lookupChunks(ctx context.Context, userID string, from, throug
542
568
543
569
incomingChunkSets := make (chan ByID )
544
570
incomingErrors := make (chan error )
545
- buckets := bigBuckets (from , through )
571
+ buckets := c . bigBuckets (from , through )
546
572
totalLookups := int32 (0 )
547
- for _ , hour := range buckets {
548
- go func (hour int64 ) {
549
- incoming , lookups , err := c .lookupChunksFor (ctx , userID , hour , metricName , matchers )
573
+ for _ , b := range buckets {
574
+ go func (bucket string ) {
575
+ incoming , lookups , err := c .lookupChunksFor (ctx , userID , bucket , metricName , matchers )
550
576
atomic .AddInt32 (& totalLookups , lookups )
551
577
if err != nil {
552
578
incomingErrors <- err
553
579
} else {
554
580
incomingChunkSets <- incoming
555
581
}
556
- }(hour )
582
+ }(b )
557
583
}
558
584
559
585
var chunks ByID
@@ -591,17 +617,17 @@ func next(s string) string {
591
617
return result
592
618
}
593
619
594
- func (c * AWSStore ) lookupChunksFor (ctx context.Context , userID string , hour int64 , metricName model.LabelValue , matchers []* metric.LabelMatcher ) (ByID , int32 , error ) {
620
+ func (c * AWSStore ) lookupChunksFor (ctx context.Context , userID string , bucket string , metricName model.LabelValue , matchers []* metric.LabelMatcher ) (ByID , int32 , error ) {
595
621
if len (matchers ) == 0 {
596
- return c .lookupChunksForMetricName (ctx , userID , hour , metricName )
622
+ return c .lookupChunksForMetricName (ctx , userID , bucket , metricName )
597
623
}
598
624
599
625
incomingChunkSets := make (chan ByID )
600
626
incomingErrors := make (chan error )
601
627
602
628
for _ , matcher := range matchers {
603
629
go func (matcher * metric.LabelMatcher ) {
604
- incoming , err := c .lookupChunksForMatcher (ctx , userID , hour , metricName , matcher )
630
+ incoming , err := c .lookupChunksForMatcher (ctx , userID , bucket , metricName , matcher )
605
631
if err != nil {
606
632
incomingErrors <- err
607
633
} else {
@@ -623,8 +649,8 @@ func (c *AWSStore) lookupChunksFor(ctx context.Context, userID string, hour int6
623
649
return nWayIntersect (chunkSets ), int32 (len (matchers )), lastErr
624
650
}
625
651
626
- func (c * AWSStore ) lookupChunksForMetricName (ctx context.Context , userID string , hour int64 , metricName model.LabelValue ) (ByID , int32 , error ) {
627
- hashValue := hashValue (userID , hour , metricName )
652
+ func (c * AWSStore ) lookupChunksForMetricName (ctx context.Context , userID string , bucket string , metricName model.LabelValue ) (ByID , int32 , error ) {
653
+ hashValue := hashValue (userID , bucket , metricName )
628
654
input := & dynamodb.QueryInput {
629
655
TableName : aws .String (c .tableName ),
630
656
KeyConditions : map [string ]* dynamodb.Condition {
@@ -664,8 +690,8 @@ func (c *AWSStore) lookupChunksForMetricName(ctx context.Context, userID string,
664
690
return chunkSet , 1 , nil
665
691
}
666
692
667
- func (c * AWSStore ) lookupChunksForMatcher (ctx context.Context , userID string , hour int64 , metricName model.LabelValue , matcher * metric.LabelMatcher ) (ByID , error ) {
668
- hashValue := hashValue (userID , hour , metricName )
693
+ func (c * AWSStore ) lookupChunksForMatcher (ctx context.Context , userID string , bucket string , metricName model.LabelValue , matcher * metric.LabelMatcher ) (ByID , error ) {
694
+ hashValue := hashValue (userID , bucket , metricName )
669
695
var rangeMinValue , rangeMaxValue []byte
670
696
if matcher .Type == metric .Equal {
671
697
nextValue := model .LabelValue (next (string (matcher .Value )))
0 commit comments