Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ec1cf05
Reconfigure ruler in docker compose.
pstibrany Sep 22, 2020
5a3e394
Extracted different sharding strategies into methods.
pstibrany Sep 22, 2020
886808b
Added support for shuffle sharding to ruler.go
pstibrany Sep 22, 2020
bc40f07
Sharding tests.
pstibrany Sep 24, 2020
a445b0c
Add tests for shuffle sharding strategy.
pstibrany Sep 24, 2020
be31633
Removed configstore.
pstibrany Sep 25, 2020
ea94aba
Return error if "common prefix" without supplied prefix is returned.
pstibrany Sep 25, 2020
7245be7
Changed replication strategy used by ruler.
pstibrany Sep 28, 2020
1205a50
Another test.
pstibrany Sep 28, 2020
120656e
Load rules for users concurrently when using shuffle sharding.
pstibrany Sep 28, 2020
2851fda
Removed extra method LoadRuleGroupsForUser, and replaced with LoadRul…
pstibrany Sep 28, 2020
8b25203
Comment.
pstibrany Sep 28, 2020
a879994
Fix comments after rename.
pstibrany Sep 28, 2020
517239b
Lint comments.
pstibrany Sep 28, 2020
affe159
Added ruler sync on ring change.
pstibrany Sep 28, 2020
6504c0a
Move ShuffleShardSeed to util package.
pstibrany Sep 28, 2020
69e7d26
Added log message.
pstibrany Sep 28, 2020
90384cd
Fix compilation of tests.
pstibrany Sep 28, 2020
198b32c
Create user-manager even if files even haven't changed.
pstibrany Sep 28, 2020
f9ebb62
Unregister user registry when removing ruler manager.
pstibrany Sep 28, 2020
b1d049f
Added short paragraph about ruler shuffle sharding.
pstibrany Sep 28, 2020
bafaa6d
Review feedback.
pstibrany Sep 29, 2020
48eccea
Modified test, it now verifies expected rules for each ruler.
pstibrany Sep 29, 2020
1e646a2
Added test for bugfix in DefaultTenantManagerFactory.
pstibrany Sep 29, 2020
e4fdda3
Added CHANGELOG.md
pstibrany Sep 29, 2020
6ccb5a4
Added test for Collect and DeleteUserRegistry.
pstibrany Sep 29, 2020
40b4266
Clean white noise.
pstibrany Sep 29, 2020
7fb3602
Move comment about replication factor.
pstibrany Sep 30, 2020
b6d047d
Added comment about tokens setup.
pstibrany Sep 30, 2020
a66091d
Fix compilation problem after master merge.
pstibrany Sep 30, 2020
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@
* [ENHANCEMENT] Reduce tail latency by smoothing out spikes in rate of chunk flush operations. #3191
* [ENHANCEMENT] Experimental Ruler API: Fetch rule groups from object storage in parallel. #3218
* [ENHANCEMENT] Chunks GCS object storage client uses the `fields` selector to limit the payload size when listing objects in the bucket. #3218
* [ENHANCEMENT] Added shuffle sharding support to ruler. Added new metric `cortex_ruler_sync_rules_total`. #3235
* [BUGFIX] No-longer-needed ingester operations for queries triggered by queriers and rulers are now canceled. #3178
* [BUGFIX] Ruler: directories in the configured `rules-path` will be removed on startup and shutdown in order to ensure they don't persist between runs. #3195
* [BUGFIX] Handle hash-collisions in the query path. #3192
* [BUGFIX] Check for postgres rows errors. #3197
* [BUGFIX] Ruler Experimental API: Don't allow rule groups without names or empty rule groups. #3210
* [BUGFIX] Experimental Alertmanager API: Do not allow empty Alertmanager configurations or bad template filenames to be submitted through the configuration API. #3185
* [BUGFIX] When using ruler sharding, moving all user rule groups from ruler to a different one and then back could end up with some user groups not being evaluated at all. #3235

## 1.4.0-rc.0 in progress

Expand Down

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions development/tsdb-blocks-storage-s3/.data-minio/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
!.gitignore
!cortex-tsdb
!cortex-alertmanager
!cortex-ruler
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
16 changes: 13 additions & 3 deletions development/tsdb-blocks-storage-s3/config/cortex.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,19 @@ blocks_storage:
ruler:
enable_api: true
storage:
type: configdb
configdb:
configs_api_url: http://configstore:80/
type: s3
s3:
bucketnames: cortex-ruler
s3forcepathstyle: true
s3: http://cortex:supersecret@minio.:9000
enable_sharding: true
ring:
heartbeat_period: 5s
heartbeat_timeout: 15s
kvstore:
store: consul
consul:
host: consul:8500

alertmanager:
enable_api: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ prometheus:
namespace: 'tsdb-blocks-storage-s3'
- job_name: tsdb-blocks-storage-s3/ruler
static_configs:
- targets: ['ruler:8005']
- targets: ['ruler-1:8021', 'ruler-2:8022']
labels:
cluster: 'docker-compose'
namespace: 'tsdb-blocks-storage-s3'
Expand Down
2 changes: 1 addition & 1 deletion development/tsdb-blocks-storage-s3/config/prometheus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ scrape_configs:
namespace: 'tsdb-blocks-storage-s3'
- job_name: tsdb-blocks-storage-s3/ruler
static_configs:
- targets: ['ruler:8005']
- targets: ['ruler-1:8021', 'ruler-2:8022']
labels:
cluster: 'docker-compose'
namespace: 'tsdb-blocks-storage-s3'
Expand Down
64 changes: 40 additions & 24 deletions development/tsdb-blocks-storage-s3/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ services:
memcached:
image: memcached:1.6

configstore:
image: nginx
volumes:
- .data-configstore:/usr/share/nginx/html/private:ro

prometheus:
image: prom/prometheus:v2.16.0
command: ["--config.file=/etc/prometheus/prometheus.yaml"]
Expand Down Expand Up @@ -178,80 +173,101 @@ services:
volumes:
- ./config:/cortex/config

ruler:
compactor:
build:
context: .
dockerfile: dev.dockerfile
image: cortex
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18005 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=ruler -server.http-listen-port=8005 -server.grpc-listen-port=9005"]
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18006 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=compactor -server.http-listen-port=8006 -server.grpc-listen-port=9006"]
depends_on:
- consul
- minio
environment:
- JAEGER_AGENT_HOST=jaeger
- JAEGER_AGENT_PORT=6831
- JAEGER_TAGS=app=ruler
- JAEGER_TAGS=app=compactor
- JAEGER_SAMPLER_TYPE=const
- JAEGER_SAMPLER_PARAM=1
ports:
- 8005:8005
- 18005:18005
- 8006:8006
- 18006:18006
volumes:
- ./config:/cortex/config

compactor:
query-frontend:
build:
context: .
dockerfile: dev.dockerfile
image: cortex
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18006 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=compactor -server.http-listen-port=8006 -server.grpc-listen-port=9006"]
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18007 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=query-frontend -server.http-listen-port=8007 -server.grpc-listen-port=9007 -store.max-query-length=8760h"]
depends_on:
- consul
- minio
environment:
- JAEGER_AGENT_HOST=jaeger
- JAEGER_AGENT_PORT=6831
- JAEGER_TAGS=app=compactor
- JAEGER_TAGS=app=query-frontend
- JAEGER_SAMPLER_TYPE=const
- JAEGER_SAMPLER_PARAM=1
ports:
- 8006:8006
- 18006:18006
- 8007:8007
- 18007:18007
volumes:
- ./config:/cortex/config

query-frontend:
alertmanager:
build:
context: .
dockerfile: dev.dockerfile
image: cortex
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18007 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=query-frontend -server.http-listen-port=8007 -server.grpc-listen-port=9007 -store.max-query-length=8760h"]
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18010 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=alertmanager -server.http-listen-port=8010 -server.grpc-listen-port=9010"]
depends_on:
- consul
- minio
ports:
- 8010:8010
- 18010:18010
volumes:
- ./config:/cortex/config

ruler-1:
build:
context: .
dockerfile: dev.dockerfile
image: cortex
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18021 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=ruler -server.http-listen-port=8021 -server.grpc-listen-port=9021"]
depends_on:
- consul
- minio
environment:
- JAEGER_AGENT_HOST=jaeger
- JAEGER_AGENT_PORT=6831
- JAEGER_TAGS=app=query-frontend
- JAEGER_TAGS=app=ruler-1
- JAEGER_SAMPLER_TYPE=const
- JAEGER_SAMPLER_PARAM=1
ports:
- 8007:8007
- 18007:18007
- 8021:8021
- 18021:18021
volumes:
- ./config:/cortex/config

alertmanager:
ruler-2:
build:
context: .
dockerfile: dev.dockerfile
image: cortex
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18010 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=alertmanager -server.http-listen-port=8010 -server.grpc-listen-port=9010"]
command: ["sh", "-c", "sleep 3 && exec ./dlv exec ./cortex --listen=:18022 --headless=true --api-version=2 --accept-multiclient --continue -- -config.file=./config/cortex.yaml -target=ruler -server.http-listen-port=8022 -server.grpc-listen-port=9022"]
depends_on:
- consul
- minio
environment:
- JAEGER_AGENT_HOST=jaeger
- JAEGER_AGENT_PORT=6831
- JAEGER_TAGS=app=ruler-2
- JAEGER_SAMPLER_TYPE=const
- JAEGER_SAMPLER_PARAM=1
ports:
- 8010:8010
- 18010:18010
- 8022:8022
- 18022:18022
volumes:
- ./config:/cortex/config
5 changes: 5 additions & 0 deletions development/tsdb-blocks-storage-s3/goland/ruler-1.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="TSDB Ruler-1" type="GoRemoteDebugConfigurationType" factoryName="Go Remote" port="18021">
<method v="2" />
</configuration>
</component>
5 changes: 5 additions & 0 deletions development/tsdb-blocks-storage-s3/goland/ruler-2.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="TSDB Ruler-2" type="GoRemoteDebugConfigurationType" factoryName="Go Remote" port="18022">
<method v="2" />
</configuration>
</component>
10 changes: 10 additions & 0 deletions docs/configuration/config-file-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,10 @@ storage:
# CLI flag: -ruler.enable-sharding
[enable_sharding: <boolean> | default = false]

# The sharding strategy to use. Supported values are: default, shuffle-sharding.
# CLI flag: -ruler.sharding-strategy
[sharding_strategy: <string> | default = "default"]

# Time to spend searching for a pending ruler when shutting down.
# CLI flag: -ruler.search-pending-for
[search_pending_for: <duration> | default = 5m]
Expand Down Expand Up @@ -2866,6 +2870,12 @@ The `limits_config` configures default and per-tenant limits imposed by Cortex s
# CLI flag: -ruler.evaluation-delay-duration
[ruler_evaluation_delay_duration: <duration> | default = 0s]

# The default tenant's shard size when the shuffle-sharding strategy is used by
# ruler. When this setting is specified in the per-tenant overrides, a value of
# 0 disables shuffle sharding for the tenant.
# CLI flag: -ruler.tenant-shard-size
[ruler_tenant_shard_size: <int> | default = 0]

# The default tenant's shard size when the shuffle-sharding strategy is used.
# Must be set when the store-gateway sharding is enabled with the
# shuffle-sharding strategy. When this setting is specified in the per-tenant
Expand Down
11 changes: 11 additions & 0 deletions docs/guides/shuffle-sharding.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Cortex currently supports shuffle sharding in the following services:
- [Ingesters](#ingesters-shuffle-sharding)
- [Query-frontend](#query-frontend-shuffle-sharding)
- [Store-gateway](#store-gateway-shuffle-sharding)
- [Ruler](#ruler-shuffle-sharding)

Shuffle sharding is **disabled by default** and needs to be explicitly enabled in the configuration.

Expand Down Expand Up @@ -92,3 +93,13 @@ When shuffle sharding is **enabled** via `-store-gateway.sharding-strategy=shuff
_The shard size can be overridden on a per-tenant basis setting `store_gateway_tenant_shard_size` in the limits overrides configuration._

_Please check out the [store-gateway documentation](../blocks-storage/store-gateway.md) for more information about how it works._

### Ruler shuffle sharding

Cortex ruler can run in three modes:

1. **No sharding at all.** This is the most basic mode of the ruler. It is activated by using `-ruler.enable-sharding=false` (default) and works correctly only if single ruler is running. In this mode the Ruler loads all rules for all tenants.
2. **Default sharding**, activated by using `-ruler.enable-sharding=true` and `-ruler.sharding-strategy=default` (default). In this mode rulers register themselves into the ring. Each ruler will then select and evaluate only those rules that it "owns".
3. **Shuffle sharding**, activated by using `-ruler.enable-sharding=true` and `-ruler.sharding-strategy=shuffle-sharding`. Similarly to default sharding, rulers use the ring to distribute workload, but rule groups for each tenant can only be evaluated on limited number of rulers (`-ruler.tenant-shard-size`, can also be set per tenant as `ruler_tenant_shard_size` in overrides).

Note that when using sharding strategy, each rule group is evaluated by single ruler only, there is no replication.
4 changes: 2 additions & 2 deletions integration/chunks_storage_backends_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func TestSwiftRuleStorage(t *testing.T) {
require.NoError(t, err)

// Get rules back.
rls, err := store.ListAllRuleGroups(ctx)
rls, err := store.LoadAllRuleGroups(ctx)
require.NoError(t, err)
require.Equal(t, 2, len(rls[userID]))

Expand All @@ -274,7 +274,7 @@ func TestSwiftRuleStorage(t *testing.T) {
require.NoError(t, err)

//Verify we only have the second rule group
rls, err = store.ListAllRuleGroups(ctx)
rls, err = store.LoadAllRuleGroups(ctx)
require.NoError(t, err)
require.Equal(t, 1, len(rls[userID]))
require.Equal(t, r2, rls[userID][0])
Expand Down
3 changes: 2 additions & 1 deletion pkg/chunk/storage_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type ReadBatchIterator interface {
Value() []byte
}

// ObjectClient is used to store arbitrary data in Object Store (S3/GCS/Azure/Etc)
// ObjectClient is used to store arbitrary data in Object Store (S3/GCS/Azure/...)
type ObjectClient interface {
PutObject(ctx context.Context, objectKey string, object io.ReadSeeker) error
GetObject(ctx context.Context, objectKey string) (io.ReadCloser, error)
Expand All @@ -85,4 +85,5 @@ type StorageObject struct {
}

// StorageCommonPrefix represents a common prefix aka a synthetic directory in Object Store.
// It is guaranteed to always end with delimiter passed to List method.
type StorageCommonPrefix string
2 changes: 1 addition & 1 deletion pkg/cortex/cortex.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (c *Config) Validate(log log.Logger) error {
if err := c.ChunkStore.Validate(); err != nil {
return errors.Wrap(err, "invalid chunk store config")
}
if err := c.Ruler.Validate(); err != nil {
if err := c.Ruler.Validate(c.LimitsConfig); err != nil {
return errors.Wrap(err, "invalid ruler config")
}
if err := c.BlocksStorage.Validate(); err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/cortex/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ func (t *Cortex) initRuler() (serv services.Service, err error) {
prometheus.DefaultRegisterer,
util.Logger,
t.RulerStorage,
t.Overrides,
)
if err != nil {
return
Expand Down
13 changes: 3 additions & 10 deletions pkg/querier/frontend/frontend_querier_queues.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package frontend

import (
"crypto/md5"
"encoding/binary"
"math/rand"
"sort"

"github.com/cortexproject/cortex/pkg/util"
)

// This struct holds user queues for pending requests. It also keeps track of connected queriers,
Expand Down Expand Up @@ -89,7 +89,7 @@ func (q *queues) getOrAddQueue(userID string, maxQueriers int) chan *request {
if uq == nil {
uq = &userQueue{
ch: make(chan *request, q.maxUserQueueSize),
seed: getSeedForUser(userID),
seed: util.ShuffleShardSeed(userID),
index: -1,
}
q.userQueues[userID] = uq
Expand Down Expand Up @@ -222,10 +222,3 @@ func shuffleQueriersForUser(userSeed int64, queriersToSelect int, allSortedQueri

return result
}

func getSeedForUser(user string) int64 {
d := md5.New()
_, _ = d.Write([]byte(user))
buf := d.Sum(nil)
return int64(binary.BigEndian.Uint64(buf))
}
3 changes: 3 additions & 0 deletions pkg/ring/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ func (i *IngesterDesc) IsHealthy(op Operation, heartbeatTimeout time.Duration) b

case BlocksRead:
healthy = i.State == ACTIVE

case Ruler:
healthy = i.State == ACTIVE
}

return healthy && time.Since(time.Unix(i.Timestamp, 0)) <= heartbeatTimeout
Expand Down
Loading