github.com/thanos-io/thanos@v0.32.5/internal/cortex/chunk/cache/background.go (about)

     1  // Copyright (c) The Cortex Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package cache
     5  
     6  import (
     7  	"context"
     8  	"flag"
     9  	"sync"
    10  
    11  	"github.com/prometheus/client_golang/prometheus"
    12  	"github.com/prometheus/client_golang/prometheus/promauto"
    13  )
    14  
    15  // BackgroundConfig is config for a Background Cache.
    16  type BackgroundConfig struct {
    17  	WriteBackGoroutines int `yaml:"writeback_goroutines"`
    18  	WriteBackBuffer     int `yaml:"writeback_buffer"`
    19  }
    20  
    21  // RegisterFlagsWithPrefix adds the flags required to config this to the given FlagSet
    22  func (cfg *BackgroundConfig) RegisterFlagsWithPrefix(prefix string, description string, f *flag.FlagSet) {
    23  	f.IntVar(&cfg.WriteBackGoroutines, prefix+"background.write-back-concurrency", 10, description+"At what concurrency to write back to cache.")
    24  	f.IntVar(&cfg.WriteBackBuffer, prefix+"background.write-back-buffer", 10000, description+"How many key batches to buffer for background write-back.")
    25  }
    26  
    27  type backgroundCache struct {
    28  	Cache
    29  
    30  	wg       sync.WaitGroup
    31  	quit     chan struct{}
    32  	bgWrites chan backgroundWrite
    33  	name     string
    34  
    35  	droppedWriteBack prometheus.Counter
    36  	queueLength      prometheus.Gauge
    37  }
    38  
    39  type backgroundWrite struct {
    40  	keys []string
    41  	bufs [][]byte
    42  }
    43  
    44  // NewBackground returns a new Cache that does stores on background goroutines.
    45  func NewBackground(name string, cfg BackgroundConfig, cache Cache, reg prometheus.Registerer) Cache {
    46  	c := &backgroundCache{
    47  		Cache:    cache,
    48  		quit:     make(chan struct{}),
    49  		bgWrites: make(chan backgroundWrite, cfg.WriteBackBuffer),
    50  		name:     name,
    51  		droppedWriteBack: promauto.With(reg).NewCounter(prometheus.CounterOpts{
    52  			Namespace:   "cortex",
    53  			Name:        "cache_dropped_background_writes_total",
    54  			Help:        "Total count of dropped write backs to cache.",
    55  			ConstLabels: prometheus.Labels{"name": name},
    56  		}),
    57  
    58  		queueLength: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
    59  			Namespace:   "cortex",
    60  			Name:        "cache_background_queue_length",
    61  			Help:        "Length of the cache background write queue.",
    62  			ConstLabels: prometheus.Labels{"name": name},
    63  		}),
    64  	}
    65  
    66  	c.wg.Add(cfg.WriteBackGoroutines)
    67  	for i := 0; i < cfg.WriteBackGoroutines; i++ {
    68  		go c.writeBackLoop()
    69  	}
    70  
    71  	return c
    72  }
    73  
    74  func (c *backgroundCache) writeBackLoop() {
    75  	defer c.wg.Done()
    76  
    77  	for {
    78  		select {
    79  		case bgWrite, ok := <-c.bgWrites:
    80  			if !ok {
    81  				return
    82  			}
    83  			c.queueLength.Sub(float64(len(bgWrite.keys)))
    84  			c.Cache.Store(context.Background(), bgWrite.keys, bgWrite.bufs)
    85  
    86  		case <-c.quit:
    87  			return
    88  		}
    89  	}
    90  }