Skip to content

Commit d988472

Browse files
authored
Do not resync blocks in running store gateways during rollout deployment and container restart (#5363)
* Do not resync blocks in running store gateways during rollout deployment and container restart Signed-off-by: Justin Jung <[email protected]> * Add changelog Signed-off-by: Justin Jung <[email protected]> * Change numScaleUpGateways in RingTopologyChangedAfterScaleUp test to be less than the replication factor Signed-off-by: Justin Jung <[email protected]> * Ignore RegisteredTimestamp in HasReplicationSetChangedWithoutStateAndAddress Signed-off-by: Justin Jung <[email protected]> --------- Signed-off-by: Justin Jung <[email protected]>
1 parent 7bb2850 commit d988472

File tree

5 files changed

+73
-11
lines changed

5 files changed

+73
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* [BUGFIX] Storage: Bucket index updater should ignore meta not found for partial blocks. #5343
2828
* [BUGFIX] Ring: Add JOINING state to read operation. #5346
2929
* [BUGFIX] Compactor: Partial block with only visit marker should be deleted even there is no deletion marker. #5342
30+
* [ENHANCEMENT] Do not resync blocks in running store gateways during rollout deployment and container restart. #5363
3031

3132
## 1.15.1 2023-04-26
3233

pkg/ring/replication_set.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,24 +127,36 @@ func (r ReplicationSet) GetAddressesWithout(exclude string) []string {
127127
return addrs
128128
}
129129

130-
// HasReplicationSetChanged returns true if two replications sets are the same (with possibly different timestamps),
131-
// false if they differ in any way (number of instances, instance states, tokens, zones, ...).
130+
// HasReplicationSetChanged returns false if two replications sets are the same (with possibly different timestamps),
131+
// true if they differ in any way (number of instances, instance states, tokens, zones, ...).
132132
func HasReplicationSetChanged(before, after ReplicationSet) bool {
133133
return hasReplicationSetChangedExcluding(before, after, func(i *InstanceDesc) {
134134
i.Timestamp = 0
135135
})
136136
}
137137

138-
// HasReplicationSetChangedWithoutState returns true if two replications sets
138+
// HasReplicationSetChangedWithoutState returns false if two replications sets
139139
// are the same (with possibly different timestamps and instance states),
140-
// false if they differ in any other way (number of instances, tokens, zones, ...).
140+
// true if they differ in any other way (number of instances, tokens, zones, ...).
141141
func HasReplicationSetChangedWithoutState(before, after ReplicationSet) bool {
142142
return hasReplicationSetChangedExcluding(before, after, func(i *InstanceDesc) {
143143
i.Timestamp = 0
144144
i.State = PENDING
145145
})
146146
}
147147

148+
// HasReplicationSetChangedWithoutStateAndAddress returns false if two replications sets
149+
// are the same (with possibly different timestamps, instance states and address),
150+
// true if they differ in any other way (number of instances, tokens, or zones).
151+
func HasReplicationSetChangedWithoutStateAndAddress(before, after ReplicationSet) bool {
152+
return hasReplicationSetChangedExcluding(before, after, func(i *InstanceDesc) {
153+
i.Timestamp = 0
154+
i.State = PENDING
155+
i.Addr = ""
156+
i.RegisteredTimestamp = 0
157+
})
158+
}
159+
148160
// Do comparison of replicasets, but apply a function first
149161
// to be able to exclude (reset) some values
150162
func hasReplicationSetChangedExcluding(before, after ReplicationSet, exclude func(*InstanceDesc)) bool {

pkg/ring/replication_set_test.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,10 @@ var (
251251
},
252252
}
253253
replicationSetChangesTestCases = map[string]struct {
254-
nextState ReplicationSet
255-
expectHasReplicationSetChanged bool
256-
expectHasReplicationSetChangedWithoutState bool
254+
nextState ReplicationSet
255+
expectHasReplicationSetChanged bool
256+
expectHasReplicationSetChangedWithoutState bool
257+
expectHasReplicationSetChangedWithoutStateAndAddress bool
257258
}{
258259
"timestamp changed": {
259260
ReplicationSet{
@@ -265,6 +266,7 @@ var (
265266
},
266267
false,
267268
false,
269+
false,
268270
},
269271
"state changed": {
270272
ReplicationSet{
@@ -276,6 +278,7 @@ var (
276278
},
277279
true,
278280
false,
281+
false,
279282
},
280283
"more instances": {
281284
ReplicationSet{
@@ -288,6 +291,30 @@ var (
288291
},
289292
true,
290293
true,
294+
true,
295+
},
296+
"less instances": {
297+
ReplicationSet{
298+
Instances: []InstanceDesc{
299+
{Addr: "127.0.0.1"},
300+
{Addr: "127.0.0.2"},
301+
},
302+
},
303+
true,
304+
true,
305+
true,
306+
},
307+
"replaced instance": {
308+
ReplicationSet{
309+
Instances: []InstanceDesc{
310+
{Addr: "127.0.0.1"},
311+
{Addr: "127.0.0.2"},
312+
{Addr: "127.0.0.5"},
313+
},
314+
},
315+
true,
316+
true,
317+
false,
291318
},
292319
}
293320
)
@@ -309,3 +336,12 @@ func TestHasReplicationSetChangedWithoutState_IgnoresTimeStampAndState(t *testin
309336
})
310337
}
311338
}
339+
340+
func TestHasReplicationSetChangedWithoutStateAndAddress_IgnoresTimeStampAndStateAndAddress(t *testing.T) {
341+
// Only testing difference to underlying Equal function
342+
for testName, testData := range replicationSetChangesTestCases {
343+
t.Run(testName, func(t *testing.T) {
344+
assert.Equal(t, testData.expectHasReplicationSetChangedWithoutStateAndAddress, HasReplicationSetChangedWithoutStateAndAddress(replicationSetChangesInitialState, testData.nextState), "HasReplicationSetChangedWithoutStateAndAddress wrong result")
345+
})
346+
}
347+
}

pkg/storegateway/gateway.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ func (g *StoreGateway) running(ctx context.Context) error {
299299
// replication set which we use to compare with the previous state.
300300
currRingState, _ := g.ring.GetAllHealthy(BlocksOwnerSync) // nolint:errcheck
301301

302-
if ring.HasReplicationSetChanged(ringLastState, currRingState) {
302+
// Ignore address when comparing to avoid block re-sync if tokens are persisted with tokens_file_path
303+
if ring.HasReplicationSetChangedWithoutStateAndAddress(ringLastState, currRingState) {
303304
ringLastState = currRingState
304305
g.syncStores(ctx, syncReasonRingChange)
305306
}

pkg/storegateway/gateway_test.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ func TestStoreGateway_BlocksSyncWithDefaultSharding_RingTopologyChangedAfterScal
382382
shardingStrategy = util.ShardingStrategyDefault
383383
replicationFactor = 3
384384
numInitialGateways = 4
385-
numScaleUpGateways = 6
385+
numScaleUpGateways = 2
386386
expectedBlocksLoaded = 3 * numBlocks // blocks are replicated 3 times
387387
)
388388

@@ -615,7 +615,7 @@ func TestStoreGateway_SyncOnRingTopologyChanged(t *testing.T) {
615615
},
616616
expectedSync: true,
617617
},
618-
"should sync when an instance changes state": {
618+
"should NOT sync when an instance changes state": {
619619
setupRing: func(desc *ring.Desc) {
620620
desc.AddIngester("instance-1", "127.0.0.1", "", ring.Tokens{1, 2, 3}, ring.ACTIVE, registeredAt)
621621
desc.AddIngester("instance-2", "127.0.0.2", "", ring.Tokens{4, 5, 6}, ring.JOINING, registeredAt)
@@ -625,7 +625,19 @@ func TestStoreGateway_SyncOnRingTopologyChanged(t *testing.T) {
625625
instance.State = ring.ACTIVE
626626
desc.Ingesters["instance-2"] = instance
627627
},
628-
expectedSync: true,
628+
expectedSync: false,
629+
},
630+
"should NOT sync when an instance address is replaced": {
631+
setupRing: func(desc *ring.Desc) {
632+
desc.AddIngester("instance-1", "127.0.0.1", "", ring.Tokens{1, 2, 3}, ring.ACTIVE, registeredAt)
633+
desc.AddIngester("instance-2", "127.0.0.2", "", ring.Tokens{4, 5, 6}, ring.JOINING, registeredAt)
634+
},
635+
updateRing: func(desc *ring.Desc) {
636+
instance := desc.Ingesters["instance-2"]
637+
instance.Addr = "127.0.0.3"
638+
desc.Ingesters["instance-2"] = instance
639+
},
640+
expectedSync: false,
629641
},
630642
"should sync when an healthy instance becomes unhealthy": {
631643
setupRing: func(desc *ring.Desc) {

0 commit comments

Comments
 (0)