Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixes ring.SetAddrs and rebalance race #2283

Merged

Conversation

AlexanderYastrebov
Copy link
Contributor

@AlexanderYastrebov AlexanderYastrebov commented Nov 15, 2022

While working on reducing ring.SetAddrs lock contention (see #2190 (comment)) I have discovered a race condition between SetAddrs and rebalance which I would like to fix first and separately.

The change consists of two commits:

  • a test to reproduce the race
  • the fix

The fix ensures atomic update of c.hash and c.shards, otherwise c.hash may return shard name that is not in the c.shards and cause ring operation panic.

BenchmarkRingRebalanceLocked shows rebalance latency if that is a concern:

go test . -run=NONE -bench=BenchmarkRingRebalanceLocked -v -count=10 | benchstat /dev/stdin
name                   time/op
RingRebalanceLocked-8  8.50µs ±14%

(Note: it essentially reverts a46b053)

Updates #2077
FYI @szuecs

@AlexanderYastrebov AlexanderYastrebov changed the title ring: fix SetAddrs and rebalance race fix: fixes SetAddrs and rebalance race Nov 15, 2022
The change ensures atomic update of `c.hash` and `c.shards`.

`BenchmarkRingRebalanceLocked` shows rebalance latency:
```
go test . -run=NONE -bench=BenchmarkRingRebalanceLocked -v -count=10 | benchstat /dev/stdin
name                   time/op
RingRebalanceLocked-8  8.50µs ±14%
```

(Note: it essentially reverts a46b053)
@AlexanderYastrebov AlexanderYastrebov force-pushed the ring/fix-set-addrs-rebalance-race branch from 7adfdca to 433975c Compare November 15, 2022 01:10
@AlexanderYastrebov AlexanderYastrebov changed the title fix: fixes SetAddrs and rebalance race fix: fixes ring.SetAddrs and rebalance race Nov 15, 2022
ring_test.go Outdated
return string(h)
}

func TestRingSetAddrsAndRebalanceRace(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please create and move this test to internal_test.go that has package redis so we don't need to export more commands in export_test.go?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved test and benchmark to internal_test.go

return c.sharding.ShardByName(name)
}

func (c *ringSharding) ShardByName(name string) *ringShard {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was only used by above ShardByName

@vmihailenco vmihailenco merged commit d83436b into redis:master Nov 21, 2022
@vmihailenco
Copy link
Collaborator

Thanks for the fix 👍

@AlexanderYastrebov AlexanderYastrebov deleted the ring/fix-set-addrs-rebalance-race branch November 21, 2022 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants