From 9014823107b92379adc0e2bd6f28f8d7d16dae18 Mon Sep 17 00:00:00 2001 From: Alan Protasio Date: Fri, 28 Jun 2024 16:10:26 -0700 Subject: [PATCH] Using Ingester Id as a tiebreaker for MinimizeSpreadTokenGenerator (#6044) Signed-off-by: alanprot --- pkg/ring/token_generator.go | 7 ++++--- pkg/ring/token_generator_test.go | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pkg/ring/token_generator.go b/pkg/ring/token_generator.go index 0948a72da0..2666421826 100644 --- a/pkg/ring/token_generator.go +++ b/pkg/ring/token_generator.go @@ -100,9 +100,10 @@ func (g *MinimizeSpreadTokenGenerator) GenerateTokens(ring *Desc, id, zone strin tokensPerInstanceWithDistance[i] = &totalTokenPerInstance{id: i, zone: instance.Zone} if len(instance.Tokens) == 0 { - // If there is more than one instance with no tokens, lets only use - // MinimizeSpread token algorithm on the last one - if instance.RegisteredTimestamp < ring.Ingesters[id].RegisteredTimestamp { + // If there is more than one ingester with no tokens, use MinimizeSpread only for the first registered ingester. + // In case of a tie, use the ingester ID as a tiebreaker. + if instance.RegisteredTimestamp < ring.Ingesters[id].RegisteredTimestamp || + (instance.RegisteredTimestamp == ring.Ingesters[id].RegisteredTimestamp && i < id) { if force { return g.innerGenerator.GenerateTokens(ring, id, zone, numTokens, true) } else { diff --git a/pkg/ring/token_generator_test.go b/pkg/ring/token_generator_test.go index 259e6ac10a..c8697d28a9 100644 --- a/pkg/ring/token_generator_test.go +++ b/pkg/ring/token_generator_test.go @@ -122,6 +122,16 @@ func TestMinimizeSpreadTokenGenerator(t *testing.T) { require.Len(t, tokens, 0) tokens = minimizeTokenGenerator.GenerateTokens(rindDesc, "pendingIngester-2", zones[0], 512, false) require.Len(t, tokens, 512) + + // Should generate tokens only for the ingesters with the smaller Id when multiples ingesters does not have tokens + // and have the same registered time + now := time.Now() + rindDesc.AddIngester("pendingIngester-1", "pendingIngester-1", zones[0], []uint32{}, PENDING, now) + rindDesc.AddIngester("pendingIngester-2", "pendingIngester-2", zones[0], []uint32{}, PENDING, now) + tokens = minimizeTokenGenerator.GenerateTokens(rindDesc, "pendingIngester-1", zones[0], 512, false) + require.Len(t, tokens, 512) + tokens = minimizeTokenGenerator.GenerateTokens(rindDesc, "pendingIngester-2", zones[0], 512, false) + require.Len(t, tokens, 0) } func generateTokensForIngesters(t *testing.T, rindDesc *Desc, prefix string, zones []string, minimizeTokenGenerator *MinimizeSpreadTokenGenerator, dups map[uint32]bool) {