Skip to content

Commit 5e7b3a2

Browse files
committed
kvserver: don't subsume self-blocking latency in scheduler latency
We noticed elevated p99s during scale testing that disappeared when disabling internal timeseries storage. The theory is that the timeseries replicas are quite busy, and the scheduler latency was (unintentionally, I argue) picking up raft **handling** latencies because it wasn't accounting for the case in which handling a replica was delayed by an inflight handling of that same replica. This commit addresses this issue, so that the scheduling latency metrics truly reflect only the scheduling latency. Fixes #147911 Release note: None
1 parent 8034bc5 commit 5e7b3a2

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

pkg/kv/kvserver/scheduler.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ func (ss *raftSchedulerShard) worker(
395395
ss.Unlock()
396396

397397
// Record the scheduling latency for the range.
398+
if buildutil.CrdbTestBuild && state.begin == 0 {
399+
log.Fatalf(ctx, "raftSchedulerShard.worker called with zero begin: %+v", state)
400+
}
398401
lat := state.begin.Elapsed()
399402
metrics.RaftSchedulerLatency.RecordValue(int64(lat))
400403

@@ -437,8 +440,7 @@ func (ss *raftSchedulerShard) worker(
437440
}
438441

439442
ss.Lock()
440-
state = ss.state[id]
441-
if state.flags == stateQueued {
443+
if ss.state[id].flags == stateQueued {
442444
// No further processing required by the range ID, clear it from the
443445
// state map.
444446
delete(ss.state, id)
@@ -464,6 +466,14 @@ func (ss *raftSchedulerShard) worker(
464466
// and the worker does not go back to sleep between the current
465467
// iteration and the next iteration, so no change to num_signals
466468
// is needed.
469+
//
470+
// NB: we overwrite state.begin unconditionally since the next processing
471+
// can not possibly happen before the current processing is done (i.e.
472+
// now). We do not want the scheduler latency to pick up the time spent
473+
// handling this replica.
474+
state = ss.state[id]
475+
state.begin = crtime.NowMono()
476+
ss.state[id] = state
467477
ss.queue.Push(id)
468478
}
469479
}
@@ -495,10 +505,11 @@ func (ss *raftSchedulerShard) enqueue1Locked(
495505
if newState.flags&stateQueued == 0 {
496506
newState.flags |= stateQueued
497507
queued++
498-
ss.queue.Push(id)
499-
}
500-
if newState.begin == 0 {
508+
if buildutil.CrdbTestBuild && newState.begin != 0 {
509+
log.Fatalf(context.Background(), "raftSchedulerShard.enqueue1Locked called with non-zero begin: %+v", newState)
510+
}
501511
newState.begin = now
512+
ss.queue.Push(id)
502513
}
503514
ss.state[id] = newState
504515
return queued

pkg/kv/kvserver/scheduler_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,7 @@ func TestSchedulerEnqueueWhileProcessing(t *testing.T) {
418418
statePost := ss.state[id]
419419
ss.Unlock()
420420

421-
// TODO(tbg): enable in follow-up commit.
422-
// assert.Zero(t, statePost.begin)
421+
assert.Zero(t, statePost.begin)
423422
assert.Equal(t, stateQueued|stateTestIntercept, statePost.flags)
424423
close(done)
425424
}

0 commit comments

Comments
 (0)