Skip to content

Commit fd91ac8

Browse files
authored
tsdb: expose stripe size option to reduce tsdb memory footprint (#2185)
Signed-off-by: Thor <[email protected]>
1 parent 9d69608 commit fd91ac8

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* `-config.expand-env`
3636
* [FEATURE] Add /config HTTP endpoint which exposes the current Cortex configuration as YAML. #2165
3737
* [FEATURE] Allow Prometheus remote write directly to ingesters. #1491
38+
* [FEATURE] Add flag `-experimental.tsdb.stripe-size` to expose TSDB stripe size option. #2185
3839
* [ENHANCEMENT] Add `status` label to `cortex_alertmanager_configs` metric to gauge the number of valid and invalid configs. #2125
3940
* [ENHANCEMENT] Cassandra Authentication: added the `custom_authenticators` config option that allows users to authenticate with cassandra clusters using password authenticators that are not approved by default in [gocql](https://github.com/gocql/gocql/blob/81b8263d9fe526782a588ef94d3fa5c6148e5d67/conn.go#L27) #2093
4041
* [ENHANCEMENT] Experimental TSDB: Export TSDB Syncer metrics from Compactor component, they are prefixed with `cortex_compactor_`. #2023

pkg/ingester/ingester_v2.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@ func (i *Ingester) createTSDB(userID string) (*userTSDB, error) {
609609
RetentionDuration: uint64(i.cfg.TSDBConfig.Retention / time.Millisecond),
610610
BlockRanges: i.cfg.TSDBConfig.BlockRanges.ToMilliseconds(),
611611
NoLockfile: true,
612+
StripeSize: i.cfg.TSDBConfig.StripeSize,
612613
})
613614
if err != nil {
614615
return nil, err

pkg/storage/tsdb/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var (
3434
errInvalidShipConcurrency = errors.New("invalid TSDB ship concurrency")
3535
errInvalidCompactionInterval = errors.New("invalid TSDB compaction interval")
3636
errInvalidCompactionConcurrency = errors.New("invalid TSDB compaction concurrency")
37+
errInvalidStripeSize = errors.New("invalid TSDB stripe size")
3738
)
3839

3940
// Config holds the config information for TSDB storage
@@ -47,6 +48,7 @@ type Config struct {
4748
BucketStore BucketStoreConfig `yaml:"bucket_store"`
4849
HeadCompactionInterval time.Duration `yaml:"head_compaction_interval"`
4950
HeadCompactionConcurrency int `yaml:"head_compaction_concurrency"`
51+
StripeSize int `yaml:"stripe_size"`
5052

5153
// MaxTSDBOpeningConcurrencyOnStartup limits the number of concurrently opening TSDB's during startup
5254
MaxTSDBOpeningConcurrencyOnStartup int `yaml:"max_tsdb_opening_concurrency_on_startup"`
@@ -114,6 +116,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
114116
f.IntVar(&cfg.MaxTSDBOpeningConcurrencyOnStartup, "experimental.tsdb.max-tsdb-opening-concurrency-on-startup", 10, "limit the number of concurrently opening TSDB's on startup")
115117
f.DurationVar(&cfg.HeadCompactionInterval, "experimental.tsdb.head-compaction-interval", 1*time.Minute, "How frequently does Cortex try to compact TSDB head. Block is only created if data covers smallest block range. Must be greater than 0 and max 5 minutes.")
116118
f.IntVar(&cfg.HeadCompactionConcurrency, "experimental.tsdb.head-compaction-concurrency", 5, "Maximum number of tenants concurrently compacting TSDB head into a new block")
119+
f.IntVar(&cfg.StripeSize, "experimental.tsdb.stripe-size", 16384, "Power of 2 to use for the number of shards of series to use in TSDB. Reducing this will decrease memory footprint, but can negatively impact performance.")
117120
}
118121

119122
// Validate the config
@@ -134,6 +137,10 @@ func (cfg *Config) Validate() error {
134137
return errInvalidCompactionConcurrency
135138
}
136139

140+
if cfg.StripeSize <= 1 || (cfg.StripeSize&(cfg.StripeSize-1)) != 0 { // ensure stripe size is a positive power of 2
141+
return errInvalidStripeSize
142+
}
143+
137144
return nil
138145
}
139146

pkg/storage/tsdb/config_test.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func TestConfig_Validate(t *testing.T) {
2020
Backend: "s3",
2121
HeadCompactionInterval: 1 * time.Minute,
2222
HeadCompactionConcurrency: 5,
23+
StripeSize: 2,
2324
},
2425
expectedErr: nil,
2526
},
@@ -28,12 +29,14 @@ func TestConfig_Validate(t *testing.T) {
2829
Backend: "gcs",
2930
HeadCompactionInterval: 1 * time.Minute,
3031
HeadCompactionConcurrency: 5,
32+
StripeSize: 2,
3133
},
3234
expectedErr: nil,
3335
},
3436
"should fail on unknown backend": {
3537
config: Config{
36-
Backend: "unknown",
38+
Backend: "unknown",
39+
StripeSize: 2,
3740
},
3841
expectedErr: errUnsupportedBackend,
3942
},
@@ -42,6 +45,7 @@ func TestConfig_Validate(t *testing.T) {
4245
Backend: "s3",
4346
ShipInterval: time.Minute,
4447
ShipConcurrency: 0,
48+
StripeSize: 2,
4549
},
4650
expectedErr: errInvalidShipConcurrency,
4751
},
@@ -52,20 +56,23 @@ func TestConfig_Validate(t *testing.T) {
5256
ShipConcurrency: 0,
5357
HeadCompactionInterval: 1 * time.Minute,
5458
HeadCompactionConcurrency: 5,
59+
StripeSize: 2,
5560
},
5661
expectedErr: nil,
5762
},
5863
"should fail on invalid compaction interval": {
5964
config: Config{
6065
Backend: "s3",
6166
HeadCompactionInterval: 0 * time.Minute,
67+
StripeSize: 2,
6268
},
6369
expectedErr: errInvalidCompactionInterval,
6470
},
6571
"should fail on too high compaction interval": {
6672
config: Config{
6773
Backend: "s3",
6874
HeadCompactionInterval: 10 * time.Minute,
75+
StripeSize: 2,
6976
},
7077
expectedErr: errInvalidCompactionInterval,
7178
},
@@ -74,6 +81,7 @@ func TestConfig_Validate(t *testing.T) {
7481
Backend: "s3",
7582
HeadCompactionInterval: time.Minute,
7683
HeadCompactionConcurrency: 0,
84+
StripeSize: 2,
7785
},
7886
expectedErr: errInvalidCompactionConcurrency,
7987
},
@@ -82,6 +90,43 @@ func TestConfig_Validate(t *testing.T) {
8290
Backend: "s3",
8391
HeadCompactionInterval: time.Minute,
8492
HeadCompactionConcurrency: 10,
93+
StripeSize: 2,
94+
},
95+
expectedErr: nil,
96+
},
97+
"should fail on negative stripe size": {
98+
config: Config{
99+
Backend: "s3",
100+
HeadCompactionInterval: 1 * time.Minute,
101+
HeadCompactionConcurrency: 5,
102+
StripeSize: -2,
103+
},
104+
expectedErr: errInvalidStripeSize,
105+
},
106+
"should fail on stripe size 0": {
107+
config: Config{
108+
Backend: "s3",
109+
HeadCompactionInterval: 1 * time.Minute,
110+
HeadCompactionConcurrency: 5,
111+
StripeSize: 0,
112+
},
113+
expectedErr: errInvalidStripeSize,
114+
},
115+
"should fail on stripe size 1": {
116+
config: Config{
117+
Backend: "s3",
118+
HeadCompactionInterval: 1 * time.Minute,
119+
HeadCompactionConcurrency: 5,
120+
StripeSize: 1,
121+
},
122+
expectedErr: errInvalidStripeSize,
123+
},
124+
"should pass on stripe size": {
125+
config: Config{
126+
Backend: "s3",
127+
HeadCompactionInterval: 1 * time.Minute,
128+
HeadCompactionConcurrency: 5,
129+
StripeSize: 1 << 14,
85130
},
86131
expectedErr: nil,
87132
},

0 commit comments

Comments
 (0)