github.com/thanos-io/thanos@v0.32.5/internal/cortex/chunk/cache/cache.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 "time" 10 11 "github.com/pkg/errors" 12 13 "github.com/go-kit/log" 14 "github.com/prometheus/client_golang/prometheus" 15 ) 16 17 // Cache byte arrays by key. 18 // 19 // NB we intentionally do not return errors in this interface - caching is best 20 // effort by definition. We found that when these methods did return errors, 21 // the caller would just log them - so its easier for implementation to do that. 22 // Whatsmore, we found partially successful Fetchs were often treated as failed 23 // when they returned an error. 24 type Cache interface { 25 Store(ctx context.Context, key []string, buf [][]byte) 26 Fetch(ctx context.Context, keys []string) (found []string, bufs [][]byte, missing []string) 27 Stop() 28 } 29 30 // Config for building Caches. 31 type Config struct { 32 EnableFifoCache bool `yaml:"enable_fifocache"` 33 34 DefaultValidity time.Duration `yaml:"default_validity"` 35 36 Background BackgroundConfig `yaml:"background"` 37 Memcache MemcachedConfig `yaml:"memcached"` 38 MemcacheClient MemcachedClientConfig `yaml:"memcached_client"` 39 Redis RedisConfig `yaml:"redis"` 40 Fifocache FifoCacheConfig `yaml:"fifocache"` 41 42 // This is to name the cache metrics properly. 43 Prefix string `yaml:"prefix" doc:"hidden"` 44 45 // For tests to inject specific implementations. 46 Cache Cache `yaml:"-"` 47 } 48 49 // RegisterFlagsWithPrefix adds the flags required to config this to the given FlagSet 50 func (cfg *Config) RegisterFlagsWithPrefix(prefix, description string, f *flag.FlagSet) { 51 cfg.Background.RegisterFlagsWithPrefix(prefix, description, f) 52 cfg.Memcache.RegisterFlagsWithPrefix(prefix, description, f) 53 cfg.MemcacheClient.RegisterFlagsWithPrefix(prefix, description, f) 54 cfg.Redis.RegisterFlagsWithPrefix(prefix, description, f) 55 cfg.Fifocache.RegisterFlagsWithPrefix(prefix, description, f) 56 57 f.BoolVar(&cfg.EnableFifoCache, prefix+"cache.enable-fifocache", false, description+"Enable in-memory cache.") 58 f.DurationVar(&cfg.DefaultValidity, prefix+"default-validity", 0, description+"The default validity of entries for caches unless overridden.") 59 60 cfg.Prefix = prefix 61 } 62 63 func (cfg *Config) Validate() error { 64 return cfg.Fifocache.Validate() 65 } 66 67 // New creates a new Cache using Config. 68 func New(cfg Config, reg prometheus.Registerer, logger log.Logger) (Cache, error) { 69 if cfg.Cache != nil { 70 return cfg.Cache, nil 71 } 72 73 caches := []Cache{} 74 75 if cfg.EnableFifoCache { 76 if cfg.Fifocache.Validity == 0 && cfg.DefaultValidity != 0 { 77 cfg.Fifocache.Validity = cfg.DefaultValidity 78 } 79 80 if cache := NewFifoCache(cfg.Prefix+"fifocache", cfg.Fifocache, reg, logger); cache != nil { 81 caches = append(caches, Instrument(cfg.Prefix+"fifocache", cache, reg)) 82 } 83 } 84 85 if (cfg.MemcacheClient.Host != "" || cfg.MemcacheClient.Addresses != "") && cfg.Redis.Endpoint != "" { 86 return nil, errors.New("use of multiple cache storage systems is not supported") 87 } 88 89 if cfg.MemcacheClient.Host != "" || cfg.MemcacheClient.Addresses != "" { 90 if cfg.Memcache.Expiration == 0 && cfg.DefaultValidity != 0 { 91 cfg.Memcache.Expiration = cfg.DefaultValidity 92 } 93 94 client := NewMemcachedClient(cfg.MemcacheClient, cfg.Prefix, reg, logger) 95 cache := NewMemcached(cfg.Memcache, client, cfg.Prefix, reg, logger) 96 97 cacheName := cfg.Prefix + "memcache" 98 caches = append(caches, NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg)) 99 } 100 101 if cfg.Redis.Endpoint != "" { 102 if cfg.Redis.Expiration == 0 && cfg.DefaultValidity != 0 { 103 cfg.Redis.Expiration = cfg.DefaultValidity 104 } 105 cacheName := cfg.Prefix + "redis" 106 redisClient, err := NewRedisClient(&cfg.Redis) 107 if err != nil { 108 return nil, errors.Errorf("creating redis client: %v", err) 109 } 110 cache := NewRedisCache(cacheName, redisClient, reg, logger) 111 caches = append(caches, NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg)) 112 } 113 114 cache := NewTiered(caches) 115 if len(caches) > 1 { 116 cache = Instrument(cfg.Prefix+"tiered", cache, reg) 117 } 118 return cache, nil 119 }