Skip to content

Commit

Permalink
Memberlist: Avoid checking for conflicting tokens if no tokens changed.
Browse files Browse the repository at this point in the history
If we can assume that the current ring state does not have conflicting
tokens, then we only need to check for conflicting tokens if the tokens
for any ingester actually changed. This will be the case for systems
not currently scaling up or down, as only heartbeats will be sent.
  • Loading branch information
stevesg committed Dec 1, 2021
1 parent 39f61cd commit a36e799
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions ring/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,17 @@ func (d *Desc) mergeWithTime(mergeable memberlist.Mergeable, localCAS bool, now
otherIngesterMap := other.Ingesters

var updated []string
tokensChanged := false

for name, oing := range otherIngesterMap {
ting := thisIngesterMap[name]
// ting.Timestamp will be 0, if there was no such ingester in our version
if oing.Timestamp > ting.Timestamp {
oing.Tokens = append([]uint32(nil), oing.Tokens...) // make a copy of tokens
thisIngesterMap[name] = oing
if !tokensEqual(ting.Tokens, oing.Tokens) {
tokensChanged = true
oing.Tokens = append([]uint32(nil), oing.Tokens...) // make a copy of tokens
thisIngesterMap[name] = oing
}
updated = append(updated, name)
} else if oing.Timestamp == ting.Timestamp && ting.State != LEFT && oing.State == LEFT {
// we accept LEFT even if timestamp hasn't changed
Expand Down Expand Up @@ -241,7 +245,7 @@ func (d *Desc) mergeWithTime(mergeable memberlist.Mergeable, localCAS bool, now
}

// resolveConflicts allocates lot of memory, so if we can avoid it, do that.
if conflictingTokensExist(thisIngesterMap) {
if tokensChanged && conflictingTokensExist(thisIngesterMap) {
resolveConflicts(thisIngesterMap)
}

Expand Down Expand Up @@ -303,6 +307,18 @@ func normalizeIngestersMap(inputRing *Desc) {
}
}

func tokensEqual(lhs, rhs []uint32) bool {
if len(lhs) != len(rhs) {
return false
}
for i := 0; i < len(lhs); i++ {
if lhs[i] != rhs[i] {
return false
}
}
return true
}

var tokenMapPool = sync.Pool{New: func() interface{} { return make(map[uint32]struct{}) }}

func conflictingTokensExist(normalizedIngesters map[string]InstanceDesc) bool {
Expand Down

0 comments on commit a36e799

Please sign in to comment.