Files
Joe ElliottandGitHub d9ccf00b3b Parquet page caching (#3196)
* page caching first pass

Signed-off-by: Joe Elliott <[email protected]>

* set default vals

Signed-off-by: Joe Elliott <[email protected]>

* actually return cache

Signed-off-by: Joe Elliott <[email protected]>

* disallow none cache

Signed-off-by: Joe Elliott <[email protected]>

* restore buffered reader

Signed-off-by: Joe Elliott <[email protected]>

* fix read buffer size

Signed-off-by: Joe Elliott <[email protected]>

* remove load

Signed-off-by: Joe Elliott <[email protected]>

* changelog

Signed-off-by: Joe Elliott <[email protected]>

* fix stopping behavior

Signed-off-by: Joe Elliott <[email protected]>

* copy before storing parquet pages

Signed-off-by: Joe Elliott <[email protected]>

* combined cached reader and optimized reader

Signed-off-by: Joe Elliott <[email protected]>

* lint/asserts

Signed-off-by: Joe Elliott <[email protected]>

* simplify needsCopy

Signed-off-by: Joe Elliott <[email protected]>

* add parquet-pages to docs

Signed-off-by: Joe Elliott <[email protected]>

* add stoewer file?

Signed-off-by: Joe Elliott <[email protected]>

* perhaps this incantation will work, mused the lonely wizard

Signed-off-by: Joe Elliott <[email protected]>

---------

Signed-off-by: Joe Elliott <[email protected]>
2023-12-15 07:42:43 -05:00

97 lines
2.4 KiB
Go

package cache
import (
"errors"
"flag"
"fmt"
"strings"
"github.com/grafana/tempo/modules/cache/memcached"
"github.com/grafana/tempo/modules/cache/redis"
"github.com/grafana/tempo/pkg/cache"
)
type Config struct {
Background *cache.BackgroundConfig `yaml:"background"`
Caches []CacheConfig `yaml:"caches"`
}
type CacheConfig struct { // nolint: revive
Role []cache.Role `yaml:"roles"`
MemcachedConfig *memcached.Config `yaml:"memcached"`
RedisConfig *redis.Config `yaml:"redis"`
}
// Validate validates the config.
func (cfg *Config) Validate() error {
claimedRoles := map[cache.Role]struct{}{}
allRoles := allRoles()
for _, cacheCfg := range cfg.Caches {
if cacheCfg.MemcachedConfig != nil && cacheCfg.RedisConfig != nil {
return fmt.Errorf("cache config for role %s has both memcached and redis configs", cacheCfg.Role)
}
if cacheCfg.MemcachedConfig == nil && cacheCfg.RedisConfig == nil {
return fmt.Errorf("cache config for role %s has neither memcached nor redis configs", cacheCfg.Role)
}
if len(cacheCfg.Role) == 0 {
return errors.New("configured caches require a valid role")
}
// check that all roles are unique
for _, role := range cacheCfg.Role {
if role == cache.RoleNone {
return fmt.Errorf("role none is not a valid role")
}
if _, ok := allRoles[role]; !ok {
return fmt.Errorf("role %s is not a valid role", role)
}
if _, ok := claimedRoles[role]; ok {
return fmt.Errorf("role %s is claimed by more than one cache", role)
}
claimedRoles[role] = struct{}{}
}
}
return nil
}
func (cfg *Config) RegisterFlagsAndApplyDefaults(_ string, _ *flag.FlagSet) {
cfg.Background = &cache.BackgroundConfig{}
cfg.Background.WriteBackBuffer = 10000
cfg.Background.WriteBackGoroutines = 10
}
// Name returns a string representation of the roles claimed by this cache.
func (cfg *CacheConfig) Name() string {
stringRoles := make([]string, len(cfg.Role))
for i, role := range cfg.Role {
stringRoles[i] = string(role)
}
return strings.Join(stringRoles, "|")
}
func allRoles() map[cache.Role]struct{} {
all := []cache.Role{
cache.RoleBloom,
cache.RoleParquetFooter,
cache.RoleParquetColumnIdx,
cache.RoleParquetOffsetIdx,
cache.RoleTraceIDIdx,
cache.RoleFrontendSearch,
cache.RoleParquetPage,
}
roles := map[cache.Role]struct{}{}
for _, role := range all {
roles[role] = struct{}{}
}
return roles
}