Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cc101b8
Moved index cache key struct outside of the file containing the in-me…
pracucci Dec 5, 2019
ba6af3d
Added cacheKey.string() to make it memcached friendly
pracucci Dec 5, 2019
0f57c95
Added MemcachedIndexCache support
pracucci Dec 12, 2019
aaa15f4
Export Prometheus metrics from MemcachedIndexCache
pracucci Dec 12, 2019
60b23d4
Fixed linter issues
pracucci Dec 12, 2019
b114623
Simplified workers wait group in memcachedClient
pracucci Dec 13, 2019
4afe30a
Fixed memcached client GetMulti() results batches channel buffer
pracucci Dec 13, 2019
bcc5ceb
Wait for addrs resolution gorouting to complete on memcachedClient.St…
pracucci Dec 16, 2019
ebd9af0
Return struct from NewMemcachedClient()
pracucci Dec 16, 2019
4581111
Update pkg/cacheutil/memcached_client.go
pracucci Dec 16, 2019
c9d37f9
Simplified memcachedClient tests
pracucci Dec 16, 2019
77413ca
Cleaned up code based on feedback
pracucci Dec 16, 2019
16d368a
Removed error from GetMulti() return and introduced metrics and traci…
pracucci Dec 16, 2019
9178cdd
Fixed compilation errors in store E2E tests
pracucci Dec 16, 2019
8951227
Added leaktest check to all tests
pracucci Dec 16, 2019
390e93c
Introduced --index.cache-config support
pracucci Dec 16, 2019
702dc82
Fixed compilation errors in store E2E tests
pracucci Dec 16, 2019
bf5dd7c
Updated store flags doc
pracucci Dec 16, 2019
fb6d122
Updated index cache doc
pracucci Dec 16, 2019
a7c20f2
Updated changelog
pracucci Dec 16, 2019
e2c72a0
Increased default memcached client timeout from 100ms to 500ms
pracucci Dec 17, 2019
f8b318e
Disabled memcached client max batch size by default
pracucci Dec 17, 2019
491c5bb
Fixed index cache key max length
pracucci Dec 17, 2019
db9356b
Removed TODO from memcached client since looks the general consensus …
pracucci Dec 17, 2019
bb3eb88
Allow to configure in-memory index cache using byte units
pracucci Dec 18, 2019
1ea97b2
Refactored index cache config file doc
pracucci Dec 18, 2019
08f1bd3
Fixed nits in comments
pracucci Dec 18, 2019
f83b2d2
Replaced hardcoded 16 with ULID calculated length based on review com…
pracucci Dec 18, 2019
b8b8517
Do not expose jumpHash func
pracucci Dec 18, 2019
f62a0b4
Updated changelog
pracucci Dec 18, 2019
b2d822e
Switched MemcachedClient GetMulti() concurrency limit to a gate
pracucci Dec 18, 2019
9113f0c
Fixed flaky tests
pracucci Dec 18, 2019
da13b4b
Fixed typos in comments
pracucci Dec 19, 2019
f1482f2
Renamed memcached config option addrs to addresses
pracucci Dec 19, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Allow to configure in-memory index cache using byte units
Signed-off-by: Marco Pracucci <marco@pracucci.com>
  • Loading branch information
pracucci committed Jan 3, 2020
commit bb3eb885a9265fa2f30b72db9d04a53fe47b8d79
2 changes: 1 addition & 1 deletion cmd/thanos/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func runStore(
indexCache, err = storecache.NewIndexCache(logger, indexCacheContentYaml, reg)
} else {
indexCache, err = storecache.NewInMemoryIndexCacheWithConfig(logger, reg, storecache.InMemoryIndexCacheConfig{
MaxSizeBytes: indexCacheSizeBytes,
MaxSizeBytes: storecache.Bytes(indexCacheSizeBytes),
MaxItemSizeBytes: storecache.DefaultInMemoryIndexCacheConfig.MaxItemSizeBytes,
})
}
Expand Down
10 changes: 5 additions & 5 deletions docs/components/store.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ Alternatively, the `in-memory` index cache can also by configured using `--index
```
type: in-memory
config:
# Maximum number of bytes the cache can contain (defaults to 250MB).
max_size_bytes: 262144000
# Maximum number of bytes the cache can contain.
max_size: 250MB

# Maximum size of a single item in the cache (defaults to 125MB).
max_item_size_bytes: 131072000
# Maximum size of a single item in the cache.
max_item_size: 125MB
```

### Memcached index cache
Expand Down Expand Up @@ -217,7 +217,7 @@ config:

# Maximum number of concurrent batch executions when fetching keys from memcached.
# Each batch can fetch up to max_get_multi_batch_size keys.
max_get_multi_batch_concurrency: 0
max_get_multi_batch_concurrency: 20

# Maximum number of keys a single underlying GetMulti() operation should run. If
# more keys are specified, internally keys are splitted into multiple batches and
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/Azure/go-autorest/autorest/validation v0.2.1-0.20191028180845-3492b2aff503 // indirect
github.com/NYTimes/gziphandler v1.1.1
github.com/OneOfOne/xxhash v1.2.6 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible
github.com/armon/go-metrics v0.3.0
github.com/aws/aws-sdk-go v1.25.35 // indirect
Expand Down
21 changes: 11 additions & 10 deletions pkg/store/cache/inmemory.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (

var (
DefaultInMemoryIndexCacheConfig = InMemoryIndexCacheConfig{
MaxSizeBytes: 250 * 1024 * 1024,
MaxItemSizeBytes: 125 * 1024 * 1024,
MaxSize: 250 * 1024 * 1024,
MaxItemSize: 125 * 1024 * 1024,
}
)

Expand All @@ -42,11 +42,12 @@ type InMemoryIndexCache struct {
overflow *prometheus.CounterVec
}

// InMemoryIndexCacheConfig holds the in-memory index cache config.
type InMemoryIndexCacheConfig struct {
// MaxSizeBytes represents overall maximum number of bytes cache can contain.
MaxSizeBytes uint64 `yaml:"max_size_bytes"`
// MaxItemSizeBytes represents maximum size of single item.
MaxItemSizeBytes uint64 `yaml:"max_item_size_bytes"`
// MaxSize represents overall maximum number of bytes cache can contain.
MaxSize Bytes `yaml:"max_size"`
// MaxItemSize represents maximum size of single item.
MaxItemSize Bytes `yaml:"max_item_size"`
}

// parseInMemoryIndexCacheConfig unmarshals a buffer into a InMemoryIndexCacheConfig with default values.
Expand All @@ -73,14 +74,14 @@ func NewInMemoryIndexCache(logger log.Logger, reg prometheus.Registerer, conf []
// NewInMemoryIndexCacheWithConfig creates a new thread-safe LRU cache for index entries and ensures the total cache
// size approximately does not exceed maxBytes.
func NewInMemoryIndexCacheWithConfig(logger log.Logger, reg prometheus.Registerer, config InMemoryIndexCacheConfig) (*InMemoryIndexCache, error) {
if config.MaxItemSizeBytes > config.MaxSizeBytes {
return nil, errors.Errorf("max item size (%v) cannot be bigger than overall cache size (%v)", config.MaxItemSizeBytes, config.MaxSizeBytes)
if config.MaxItemSize > config.MaxSize {
return nil, errors.Errorf("max item size (%v) cannot be bigger than overall cache size (%v)", config.MaxItemSize, config.MaxSize)
}

c := &InMemoryIndexCache{
logger: logger,
maxSizeBytes: config.MaxSizeBytes,
maxItemSizeBytes: config.MaxItemSizeBytes,
maxSizeBytes: uint64(config.MaxSize),
maxItemSizeBytes: uint64(config.MaxItemSize),
}

c.evicted = prometheus.NewCounterVec(prometheus.CounterOpts{
Expand Down
30 changes: 15 additions & 15 deletions pkg/store/cache/inmemory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,27 @@ func TestNewInMemoryIndexCache(t *testing.T) {
conf = []byte{}
cache, err = NewInMemoryIndexCache(log.NewNopLogger(), nil, conf)
testutil.Ok(t, err)
testutil.Equals(t, DefaultInMemoryIndexCacheConfig.MaxSizeBytes, cache.maxSizeBytes)
testutil.Equals(t, DefaultInMemoryIndexCacheConfig.MaxItemSizeBytes, cache.maxItemSizeBytes)
testutil.Equals(t, uint64(DefaultInMemoryIndexCacheConfig.MaxSize), cache.maxSizeBytes)
testutil.Equals(t, uint64(DefaultInMemoryIndexCacheConfig.MaxItemSize), cache.maxItemSizeBytes)

// Should instance an in-memory index cache with specified YAML config.
// Should instance an in-memory index cache with specified YAML config.s with units.
conf = []byte(`
max_size_bytes: 200
max_item_size_bytes: 100
max_size: 1MB
max_item_size: 2KB
`)
cache, err = NewInMemoryIndexCache(log.NewNopLogger(), nil, conf)
testutil.Ok(t, err)
testutil.Equals(t, uint64(200), cache.maxSizeBytes)
testutil.Equals(t, uint64(100), cache.maxItemSizeBytes)
testutil.Equals(t, uint64(1024*1024), cache.maxSizeBytes)
testutil.Equals(t, uint64(2*1024), cache.maxItemSizeBytes)
}

func TestInMemoryIndexCache_AvoidsDeadlock(t *testing.T) {
defer leaktest.CheckTimeout(t, 10*time.Second)()

metrics := prometheus.NewRegistry()
cache, err := NewInMemoryIndexCacheWithConfig(log.NewNopLogger(), metrics, InMemoryIndexCacheConfig{
MaxItemSizeBytes: sliceHeaderSize + 5,
MaxSizeBytes: sliceHeaderSize + 5,
MaxItemSize: sliceHeaderSize + 5,
MaxSize: sliceHeaderSize + 5,
})
testutil.Ok(t, err)

Expand Down Expand Up @@ -105,8 +105,8 @@ func TestInMemoryIndexCache_UpdateItem(t *testing.T) {

metrics := prometheus.NewRegistry()
cache, err := NewInMemoryIndexCacheWithConfig(log.NewSyncLogger(errorLogger), metrics, InMemoryIndexCacheConfig{
MaxItemSizeBytes: maxSize,
MaxSizeBytes: maxSize,
MaxItemSize: maxSize,
MaxSize: maxSize,
})
testutil.Ok(t, err)

Expand Down Expand Up @@ -191,8 +191,8 @@ func TestInMemoryIndexCache_MaxNumberOfItemsHit(t *testing.T) {

metrics := prometheus.NewRegistry()
cache, err := NewInMemoryIndexCacheWithConfig(log.NewNopLogger(), metrics, InMemoryIndexCacheConfig{
MaxItemSizeBytes: 2*sliceHeaderSize + 10,
MaxSizeBytes: 2*sliceHeaderSize + 10,
MaxItemSize: 2*sliceHeaderSize + 10,
MaxSize: 2*sliceHeaderSize + 10,
})
testutil.Ok(t, err)

Expand Down Expand Up @@ -225,8 +225,8 @@ func TestInMemoryIndexCache_Eviction_WithMetrics(t *testing.T) {

metrics := prometheus.NewRegistry()
cache, err := NewInMemoryIndexCacheWithConfig(log.NewNopLogger(), metrics, InMemoryIndexCacheConfig{
MaxItemSizeBytes: 2*sliceHeaderSize + 5,
MaxSizeBytes: 2*sliceHeaderSize + 5,
MaxItemSize: 2*sliceHeaderSize + 5,
MaxSize: 2*sliceHeaderSize + 5,
})
testutil.Ok(t, err)

Expand Down
29 changes: 29 additions & 0 deletions pkg/store/cache/units.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package storecache

import (
"github.com/alecthomas/units"
)

// Bytes is a data type which supports yaml serialization/deserialization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this 👍

// with units.
type Bytes uint64

func (b *Bytes) UnmarshalYAML(unmarshal func(interface{}) error) error {
var value string
err := unmarshal(&value)
if err != nil {
return err
}

bytes, err := units.ParseBase2Bytes(value)
if err != nil {
return err
}

*b = Bytes(bytes)
return nil
}

func (b *Bytes) MarshalYAML() (interface{}, error) {
return units.Base2Bytes(*b).String(), nil
}
21 changes: 21 additions & 0 deletions pkg/store/cache/units_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package storecache

import (
"testing"

"github.com/thanos-io/thanos/pkg/testutil"
"gopkg.in/yaml.v2"
)

func TestBytes_Marshalling(t *testing.T) {
value := Bytes(1048576)

encoded, err := yaml.Marshal(&value)
testutil.Ok(t, err)
testutil.Equals(t, "1MiB\n", string(encoded))

var decoded Bytes
err = yaml.Unmarshal(encoded, &decoded)
testutil.Equals(t, value, decoded)
testutil.Ok(t, err)
}