Skip to content

Commit b4a27d9

Browse files
pstibranypracucci
authored andcommitted
Remove remaining support for denormalised tokens in the ring. (#2034)
* Removed all support for denormalised tokens in the ring. Signed-off-by: Peter Štibraný <[email protected]> * Added CHANGELOG.md entry. Signed-off-by: Peter Štibraný <[email protected]> * Updated CHANGELOG.md entry. Signed-off-by: Peter Štibraný <[email protected]> * Updated CHANGELOG.md entry. Signed-off-by: Peter Štibraný <[email protected]> * Updated documentation. Signed-off-by: Peter Štibraný <[email protected]> * Updated documentation. Signed-off-by: Peter Štibraný <[email protected]> * Don't reserve field. We don't expect to mix very old and very new Cortex. Signed-off-by: Peter Štibraný <[email protected]> * Removed normalized comment. Check for duplicates without building map. Signed-off-by: Peter Štibraný <[email protected]> * Removed reserved fields and comment. We don't expect to run a mix of old (with old fields) and new (with new field with the same number) Cortex versions in practice. Signed-off-by: Peter Štibraný <[email protected]> * Put back reserved fields. Signed-off-by: Peter Štibraný <[email protected]> * Fixed text. Signed-off-by: Peter Štibraný <[email protected]> * Renamed migrateRing to getTokens. Signed-off-by: Peter Štibraný <[email protected]>
1 parent d68d3ab commit b4a27d9

File tree

12 files changed

+108
-683
lines changed

12 files changed

+108
-683
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ instructions below to upgrade your Postgres.
2424
* [CHANGE] Overrides mechanism has been renamed to "runtime config", and is now separate from limits. Runtime config is simply a file that is reloaded by Cortex every couple of seconds. Limits and now also multi KV use this mechanism.<br />New arguments were introduced: `-runtime-config.file` (defaults to empty) and `-runtime-config.reload-period` (defaults to 10 seconds), which replace previously used `-limits.per-user-override-config` and `-limits.per-user-override-period` options. Old options are still used if `-runtime-config.file` is not specified. This change is also reflected in YAML configuration, where old `limits.per_tenant_override_config` and `limits.per_tenant_override_period` fields are replaced with `runtime_config.file` and `runtime_config.period` respectively. #1749
2525
* [CHANGE] Cortex now rejects data with duplicate labels. Previously, such data was accepted, with duplicate labels removed with only one value left. #1964
2626
* [CHANGE] Changed the default value for `-distributor.ha-tracker.prefix` from `collectors/` to `ha-tracker/` in order to not clash with other keys (ie. ring) stored in the same key-value store. #1940
27+
* [CHANGE] Removed remaining support for using denormalised tokens in the ring. If you're still running ingesters with denormalised tokens (Cortex 0.4 or earlier, with `-ingester.normalise-tokens=false`), such ingesters will now be completely invisible to distributors and need to be either switched to Cortex 0.6.0 or later, or be configured to use normalised tokens. #2034
2728
* [FEATURE] The distributor can now drop labels from samples (similar to the removal of the replica label for HA ingestion) per user via the `distributor.drop-label` flag. #1726
2829
* [FEATURE] Added flag `debug.mutex-profile-fraction` to enable mutex profiling #1969
2930
* [FEATURE] Added `global` ingestion rate limiter strategy. Deprecated `-distributor.limiter-reload-period` flag. #1766

docs/configuration/arguments.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,9 @@ It also talks to a KVStore and has it's own copies of the same flags used by the
273273

274274
Deprecated. New ingesters always write "normalised" tokens to the ring. Normalised tokens consume less memory to encode and decode; as the ring is unmarshalled regularly, this significantly reduces memory usage of anything that watches the ring.
275275

276-
Cortex 0.4.0 is the last version that can *write* denormalised tokens. Cortex 0.5.0 and later will always *write* normalised tokens, although it can still *read* denormalised tokens written by older ingesters.
276+
Cortex 0.4.0 is the last version that can *write* denormalised tokens. Cortex 0.5.0 and above always write normalised tokens.
277277

278-
It's perfectly OK to have a mix of ingesters running denormalised (<= 0.4.0) and normalised tokens (either by using `-ingester.normalise-tokens` in Cortex <= 0.4.0, or Cortex 0.5.0+) during upgrades.
278+
Cortex 0.6.0 is the last version that can *read* denormalised tokens. Starting with Cortex 0.7.0 only normalised tokens are supported, and ingesters writing denormalised tokens to the ring (running Cortex 0.4.0 or earlier with `-ingester.normalise-tokens=false`) are ignored by distributors. Such ingesters should either switch to using normalised tokens, or be upgraded to Cortex 0.5.0 or later.
279279

280280
- `-ingester.chunk-encoding`
281281

pkg/ring/http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (r *Ring) ServeHTTP(w http.ResponseWriter, req *http.Request) {
118118
sort.Strings(ingesterIDs)
119119

120120
ingesters := []interface{}{}
121-
tokens, owned := countTokens(r.ringDesc)
121+
tokens, owned := countTokens(r.ringDesc, r.ringTokens)
122122
for _, id := range ingesterIDs {
123123
ing := r.ringDesc.Ingesters[id]
124124
timestamp := time.Unix(ing.Timestamp, 0)

pkg/ring/lifecycler_test.go

Lines changed: 7 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -43,92 +43,12 @@ func testLifecyclerConfig(ringConfig Config, id string) LifecyclerConfig {
4343
return lifecyclerConfig
4444
}
4545

46-
func checkDenormalisedLeaving(d interface{}, id string) bool {
47-
desc, ok := d.(*Desc)
48-
return ok &&
49-
len(desc.Ingesters) == 1 &&
50-
desc.Ingesters[id].State == LEAVING &&
51-
len(desc.Ingesters[id].Tokens) == 0 &&
52-
len(desc.Tokens) == 1
53-
}
54-
5546
func checkNormalised(d interface{}, id string) bool {
5647
desc, ok := d.(*Desc)
5748
return ok &&
5849
len(desc.Ingesters) == 1 &&
5950
desc.Ingesters[id].State == ACTIVE &&
60-
len(desc.Ingesters[id].Tokens) == 1 &&
61-
len(desc.Tokens) == 0
62-
}
63-
64-
func TestRingNormaliseMigration(t *testing.T) {
65-
var ringConfig Config
66-
flagext.DefaultValues(&ringConfig)
67-
ringConfig.KVStore.Mock = consul.NewInMemoryClient(GetCodec())
68-
69-
r, err := New(ringConfig, "ingester", IngesterRingKey)
70-
require.NoError(t, err)
71-
defer r.Stop()
72-
73-
// Add an 'ingester' with denormalised tokens.
74-
lifecyclerConfig1 := testLifecyclerConfig(ringConfig, "ing1")
75-
76-
// Since code to insert ingester with denormalised tokens into ring was removed,
77-
// instead of running lifecycler, we do it manually here.
78-
token := uint32(0)
79-
err = r.KVClient.CAS(context.Background(), IngesterRingKey, func(in interface{}) (out interface{}, retry bool, err error) {
80-
require.Nil(t, in)
81-
r := NewDesc()
82-
tks := GenerateTokens(lifecyclerConfig1.NumTokens, nil)
83-
r.Ingesters[lifecyclerConfig1.ID] = IngesterDesc{
84-
Addr: lifecyclerConfig1.Addr,
85-
Timestamp: time.Now().Unix(),
86-
State: LEAVING, // expected by second ingester`
87-
}
88-
for _, t := range tks {
89-
r.Tokens = append(r.Tokens, TokenDesc{
90-
Token: t,
91-
Ingester: lifecyclerConfig1.ID,
92-
})
93-
}
94-
token = tks[0]
95-
return r, true, nil
96-
})
97-
require.NoError(t, err)
98-
99-
// Check this ingester joined, is active, and has one token.
100-
test.Poll(t, 1000*time.Millisecond, true, func() interface{} {
101-
d, err := r.KVClient.Get(context.Background(), IngesterRingKey)
102-
require.NoError(t, err)
103-
return checkDenormalisedLeaving(d, "ing1")
104-
})
105-
106-
// Add a second ingester with normalised tokens.
107-
var lifecyclerConfig2 = testLifecyclerConfig(ringConfig, "ing2")
108-
lifecyclerConfig2.JoinAfter = 100 * time.Second
109-
110-
l2, err := NewLifecycler(lifecyclerConfig2, &flushTransferer{}, "ingester", IngesterRingKey, true)
111-
require.NoError(t, err)
112-
l2.Start()
113-
114-
// Since there is nothing that would make l2 to claim tokens from l1 (normally done on transfer)
115-
// we do it manually.
116-
require.NoError(t, l2.ClaimTokensFor(context.Background(), "ing1"))
117-
require.NoError(t, l2.ChangeState(context.Background(), ACTIVE))
118-
119-
// Check the new ingester joined, has the same token, and is active.
120-
test.Poll(t, 1000*time.Millisecond, true, func() interface{} {
121-
d, err := r.KVClient.Get(context.Background(), IngesterRingKey)
122-
require.NoError(t, err)
123-
124-
if desc, ok := d.(*Desc); ok {
125-
// lifecycler for ingester 1 isn't running, so we need to delete it manually
126-
// (to make checkNormalised happy)
127-
delete(desc.Ingesters, lifecyclerConfig1.ID)
128-
}
129-
return checkNormalised(d, "ing2") &&
130-
d.(*Desc).Ingesters["ing2"].Tokens[0] == token
131-
})
51+
len(desc.Ingesters[id].Tokens) == 1
13252
}
13353

13454
func TestLifecycler_HealthyInstancesCount(t *testing.T) {
@@ -381,8 +301,7 @@ func TestTokensOnDisk(t *testing.T) {
381301
return ok &&
382302
len(desc.Ingesters) == 1 &&
383303
desc.Ingesters["ing1"].State == ACTIVE &&
384-
len(desc.Ingesters["ing1"].Tokens) == 512 &&
385-
len(desc.Tokens) == 0
304+
len(desc.Ingesters["ing1"].Tokens) == 512
386305
})
387306

388307
l1.Shutdown()
@@ -406,8 +325,7 @@ func TestTokensOnDisk(t *testing.T) {
406325
return ok &&
407326
len(desc.Ingesters) == 1 &&
408327
desc.Ingesters["ing2"].State == ACTIVE &&
409-
len(desc.Ingesters["ing2"].Tokens) == 512 &&
410-
len(desc.Tokens) == 0
328+
len(desc.Ingesters["ing2"].Tokens) == 512
411329
})
412330

413331
// Check for same tokens.
@@ -441,15 +359,8 @@ func TestJoinInLeavingState(t *testing.T) {
441359
State: LEAVING,
442360
Tokens: []uint32{1, 4},
443361
},
444-
},
445-
Tokens: []TokenDesc{
446-
{
447-
Ingester: "ing2",
448-
Token: 2,
449-
},
450-
{
451-
Ingester: "ing2",
452-
Token: 3,
362+
"ing2": {
363+
Tokens: []uint32{2, 3},
453364
},
454365
},
455366
}
@@ -468,9 +379,9 @@ func TestJoinInLeavingState(t *testing.T) {
468379
require.NoError(t, err)
469380
desc, ok := d.(*Desc)
470381
return ok &&
471-
len(desc.Ingesters) == 1 &&
382+
len(desc.Ingesters) == 2 &&
472383
desc.Ingesters["ing1"].State == ACTIVE &&
473384
len(desc.Ingesters["ing1"].Tokens) == cfg.NumTokens &&
474-
len(desc.Tokens) == 2
385+
len(desc.Ingesters["ing2"].Tokens) == 2
475386
})
476387
}

0 commit comments

Comments
 (0)