@@ -13,6 +13,7 @@ import (
13
13
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/gossip"
14
14
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/history"
15
15
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/metrics"
16
+ "github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/mmaintegration"
16
17
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/op"
17
18
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/queue"
18
19
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/scheduled"
@@ -29,8 +30,8 @@ type Simulator struct {
29
30
curr time.Time
30
31
end time.Time
31
32
// interval is the step between ticks for active simulaton components, such
32
- // as the queues, store rebalancer and state changers. It should be set
33
- // lower than the bgInterval, as updated occur more frequently.
33
+ // as the queues, store rebalancer and state changers. It should be set lower
34
+ // than the bgInterval, as updates occur more frequently.
34
35
interval time.Duration
35
36
36
37
// The simulator can run multiple workload Generators in parallel.
@@ -47,6 +48,8 @@ type Simulator struct {
47
48
sqs map [state.StoreID ]queue.RangeQueue
48
49
// Store rebalancers.
49
50
srs map [state.StoreID ]storerebalancer.StoreRebalancer
51
+ // Multi-metric store rebalancers.
52
+ mmSRs map [state.StoreID ]* mmaintegration.MMAStoreRebalancer
50
53
// Store operation controllers.
51
54
controllers map [state.StoreID ]op.Controller
52
55
@@ -87,6 +90,7 @@ func NewSimulator(
87
90
lqs := make (map [state.StoreID ]queue.RangeQueue )
88
91
sqs := make (map [state.StoreID ]queue.RangeQueue )
89
92
srs := make (map [state.StoreID ]storerebalancer.StoreRebalancer )
93
+ mmSRs := make (map [state.StoreID ]* mmaintegration.MMAStoreRebalancer )
90
94
changer := state .NewReplicaChanger ()
91
95
controllers := make (map [state.StoreID ]op.Controller )
92
96
@@ -103,6 +107,7 @@ func NewSimulator(
103
107
sqs : sqs ,
104
108
controllers : controllers ,
105
109
srs : srs ,
110
+ mmSRs : mmSRs ,
106
111
pacers : pacers ,
107
112
gossip : gossip .NewGossip (initialState , settings ),
108
113
metrics : m ,
@@ -133,19 +138,24 @@ func (s *Simulator) StoreAddNotify(storeID state.StoreID, _ state.State) {
133
138
func (s * Simulator ) addStore (storeID state.StoreID , tick time.Time ) {
134
139
allocator := s .state .Allocator (storeID )
135
140
storePool := s .state .StorePool (storeID )
141
+ store , _ := s .state .Store (storeID )
136
142
s .rqs [storeID ] = queue .NewReplicateQueue (
137
143
storeID ,
144
+ store .NodeID (),
138
145
s .changer ,
139
146
s .settings ,
140
147
allocator ,
148
+ s .state .Node (store .NodeID ()).AllocatorSync (),
141
149
storePool ,
142
150
tick ,
143
151
)
144
152
s .lqs [storeID ] = queue .NewLeaseQueue (
145
153
storeID ,
154
+ store .NodeID (),
146
155
s .changer ,
147
156
s .settings ,
148
157
allocator ,
158
+ s .state .Node (store .NodeID ()).AllocatorSync (),
149
159
storePool ,
150
160
tick ,
151
161
)
@@ -175,6 +185,25 @@ func (s *Simulator) addStore(storeID state.StoreID, tick time.Time) {
175
185
s .settings ,
176
186
storerebalancer .GetStateRaftStatusFn (s .state ),
177
187
)
188
+ // TODO: We add the store to every node's allocator in the cluster
189
+ // immediately. This is also updated via gossip, however there is a delay
190
+ // after startup. When calling `mma.ProcessStoreLeaseholderMsg` via
191
+ // tickMMStoreRebalancers, there may be not be a store state for some
192
+ // replicas. Setting it here ensures that the store is always present and
193
+ // initiated in each node's allocator. We should instead handle this in mma,
194
+ // or integration component.
195
+ for _ , node := range s .state .Nodes () {
196
+ node .MMAllocator ().SetStore (state .StoreAttrAndLocFromDesc (
197
+ s .state .StoreDescriptors (false , storeID )[0 ]))
198
+ }
199
+ s .mmSRs [storeID ] = mmaintegration .NewMMAStoreRebalancer (
200
+ storeID ,
201
+ store .NodeID (),
202
+ s .state .Node (store .NodeID ()).MMAllocator (),
203
+ s .state .Node (store .NodeID ()).AllocatorSync (),
204
+ s .controllers [storeID ],
205
+ s .settings ,
206
+ )
178
207
}
179
208
180
209
// GetNextTickTime returns a simulated tick time, or an indication that the
@@ -242,6 +271,9 @@ func (s *Simulator) RunSim(ctx context.Context) {
242
271
// Simulate the store rebalancer logic.
243
272
s .tickStoreRebalancers (ctx , tick , stateForAlloc )
244
273
274
+ // Simulate the multi-metric store rebalancer logic.
275
+ s .tickMMStoreRebalancers (ctx , tick , stateForAlloc )
276
+
245
277
// Print tick metrics.
246
278
s .tickMetrics (ctx , tick )
247
279
}
@@ -342,6 +374,16 @@ func (s *Simulator) tickStoreRebalancers(ctx context.Context, tick time.Time, st
342
374
}
343
375
}
344
376
377
+ // tickStoreRebalancers iterates over the multi-metric store rebalancers in the
378
+ // cluster and ticks their control loop.
379
+ func (s * Simulator ) tickMMStoreRebalancers (ctx context.Context , tick time.Time , state state.State ) {
380
+ stores := s .state .Stores ()
381
+ s .shuffler (len (stores ), func (i , j int ) { stores [i ], stores [j ] = stores [j ], stores [i ] })
382
+ for _ , store := range stores {
383
+ s .mmSRs [store .StoreID ()].Tick (ctx , tick , state )
384
+ }
385
+ }
386
+
345
387
// tickMetrics prints the metrics up to the given tick.
346
388
func (s * Simulator ) tickMetrics (ctx context.Context , tick time.Time ) {
347
389
s .metrics .Tick (ctx , tick , s .state )
0 commit comments