Commit 6173f58
committed
perf(redis): empty-zset fast path for BZPOPMIN signal-driven wakes
Production profile after #666 deploy showed BZPOPMIN still taking
47.76 percent of n1 leader CPU (down from 86.56 percent pre-deploy
but not eliminated). Per-wake breakdown: each tryBZPopMin runs
keyTypeAtExpect, the zset prefix probe misses on the empty queue,
so the slow-path fallback re-issues all ~19 keyTypeAt seeks just
to confirm "still empty". On a busy queue with ZADD signals firing
at the producer rate, this baseline grows linearly with the wake
rate.
Add a fast variant for the signal-driven-wake case:
- keyTypeAtExpectFast: probes only the expected type's prefixes
(3 seeks for zset). On a miss, returns redisTypeNone immediately
without rawKeyTypeAt's 16 follow-up seeks and without the
hasHigherPriorityStringEncoding guard.
- tryBZPopMinFast: tryBZPopMin variant that uses keyTypeAtExpectFast.
No wrongType detection on the type-check step (the load step
itself still surfaces obvious corruption).
- waitForBlockedCommandUpdate now returns true iff the wake came
from a Signal channel (false on fallback timer / handlerCtx
cancellation).
- bzpopminWaitLoop tracks the wake reason and threads it as a
fast bool into bzpopminTryAllKeys / tryBZPopMin{,Fast}. First
iteration is always full; signal-driven wakes flip to fast;
fallback-timer wakes flip back to full.
The wrongType-detection invariant is preserved because
zsetWaiters.Signal only fires on ZADD / ZINCRBY (the only writes
that produce zset rows visible to the fast probe). A
wrongType-introducing write (HSET, SET, XADD on the same user key)
does not fire Signal, so the fallback timer's full check is the
safety net that detects it within ~one redisBlockWaitFallback
(100 ms). Initial-iteration wrongType detection is unchanged.
Behavior change: a HSET / SET / XADD that arrives mid-BLOCK on a
key being BZPOPMINed surfaces WRONGTYPE within ~100 ms instead of
immediately. Previous behavior surfaced WRONGTYPE within ~10 ms
under the busy-poll, ~100 ms under #666's fallback (this PR keeps
the same 100 ms ceiling). No correctness regression for existing
contracts (initial wrongType, BLOCK-timeout-returns-nil).
Test coverage:
- TestRedis_BZPopMinRejectsInitialWrongType (new): pre-existing
string at the BZPOPMIN target key surfaces WRONGTYPE on the very
first iteration's full check, well under the BLOCK timeout.
- TestRedis_BZPopMinDetectsMidBlockWrongType (new): SET arriving
during a BZPOPMIN BLOCK surfaces WRONGTYPE through the fallback-
timer full check before the BLOCK budget elapses. Locks down the
fallback safety net.
- Existing TestRedis_BZPopMinWakesOnZAdd / WakesOnZIncrBy /
TimesOutOnEmptyKey continue to lock down the signal path and
the deadline contract.
Self-review (CLAUDE.md 5 lenses):
1. Data loss -- None. Read-only fast path; persistBZPopMinResult
is unchanged.
2. Concurrency -- waitForBlockedCommandUpdate's new bool return is
set under the same select that already serialised the three
wake sources; no new shared state.
3. Performance -- 16 fewer Pebble seeks per signal-driven wake on
empty queues. The number of wakes per BZPOPMIN is unchanged --
this is per-wake cost reduction, not wake-rate reduction.
4. Data consistency -- Signal-driven wake reads at a fresh readTS;
the fast probe and the slow probe see the same MVCC snapshot.
wrongType detection on the slow path is preserved on initial
iteration and on every fallback wake.
5. Test coverage -- two new lockdown tests for the wrongType paths
that cannot regress silently if the fast / full mode flag is
wired incorrectly.1 parent 53c687d commit 6173f58
3 files changed
Lines changed: 175 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
122 | 198 | | |
123 | 199 | | |
124 | 200 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3651 | 3651 | | |
3652 | 3652 | | |
3653 | 3653 | | |
| 3654 | + | |
| 3655 | + | |
| 3656 | + | |
| 3657 | + | |
| 3658 | + | |
| 3659 | + | |
| 3660 | + | |
| 3661 | + | |
| 3662 | + | |
| 3663 | + | |
| 3664 | + | |
| 3665 | + | |
| 3666 | + | |
| 3667 | + | |
| 3668 | + | |
| 3669 | + | |
| 3670 | + | |
3654 | 3671 | | |
3655 | 3672 | | |
3656 | 3673 | | |
3657 | 3674 | | |
3658 | 3675 | | |
3659 | | - | |
| 3676 | + | |
| 3677 | + | |
| 3678 | + | |
| 3679 | + | |
| 3680 | + | |
| 3681 | + | |
| 3682 | + | |
3660 | 3683 | | |
3661 | 3684 | | |
3662 | 3685 | | |
| |||
3763 | 3786 | | |
3764 | 3787 | | |
3765 | 3788 | | |
| 3789 | + | |
| 3790 | + | |
| 3791 | + | |
| 3792 | + | |
| 3793 | + | |
| 3794 | + | |
| 3795 | + | |
| 3796 | + | |
| 3797 | + | |
| 3798 | + | |
| 3799 | + | |
3766 | 3800 | | |
3767 | 3801 | | |
3768 | 3802 | | |
3769 | 3803 | | |
3770 | 3804 | | |
3771 | | - | |
| 3805 | + | |
3772 | 3806 | | |
3773 | 3807 | | |
3774 | 3808 | | |
3775 | 3809 | | |
3776 | 3810 | | |
3777 | 3811 | | |
3778 | | - | |
| 3812 | + | |
3779 | 3813 | | |
3780 | 3814 | | |
3781 | 3815 | | |
3782 | 3816 | | |
3783 | 3817 | | |
3784 | | - | |
3785 | | - | |
| 3818 | + | |
| 3819 | + | |
| 3820 | + | |
| 3821 | + | |
3786 | 3822 | | |
3787 | | - | |
| 3823 | + | |
| 3824 | + | |
| 3825 | + | |
| 3826 | + | |
| 3827 | + | |
| 3828 | + | |
| 3829 | + | |
3788 | 3830 | | |
3789 | 3831 | | |
3790 | 3832 | | |
| |||
3812 | 3854 | | |
3813 | 3855 | | |
3814 | 3856 | | |
3815 | | - | |
| 3857 | + | |
| 3858 | + | |
| 3859 | + | |
| 3860 | + | |
| 3861 | + | |
| 3862 | + | |
| 3863 | + | |
| 3864 | + | |
| 3865 | + | |
| 3866 | + | |
3816 | 3867 | | |
3817 | 3868 | | |
3818 | 3869 | | |
| |||
3832 | 3883 | | |
3833 | 3884 | | |
3834 | 3885 | | |
| 3886 | + | |
3835 | 3887 | | |
| 3888 | + | |
3836 | 3889 | | |
| 3890 | + | |
3837 | 3891 | | |
3838 | 3892 | | |
3839 | 3893 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
363 | 363 | | |
364 | 364 | | |
365 | 365 | | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
366 | 404 | | |
367 | 405 | | |
368 | 406 | | |
| |||
0 commit comments