Commit ef9b8e2
authored
perf(redis): keyTypeAt fast path for stream/hash/zset commands (#665)
## Summary
- `keyTypeAt` was the leader's #2 CPU consumer in production (74.8% of
the 30s pprof, on top of XREAD busy-poll which #663 addresses). Each
call issues up to ~19 Pebble seeks across every collection family before
returning.
- Add `keyTypeAtExpect(ctx, key, readTS, expected)` — probes only the
prefixes for the expected type (2–3 seeks). On hit, applies the TTL
filter and returns; on miss, falls through to the full `keyTypeAt` slow
path so wrongType detection is preserved.
- Convert 21 stream / hash / zset call sites to the fast path. Set /
list / string / mixed-kind callers are left for a follow-up.
## CPU savings
| Branch | Slow path (before) | Fast path (this PR, hit) | Reduction |
|---|---:|---:|---:|
| Stream (XADD/XREAD/XLEN/XRANGE) | ~19 seeks | 2 seeks | 9.5× |
| Hash (HSET/HGET/HDEL/HLEN/HMGET/HEXISTS/HGETALL/HINCRBY) | ~19 | 3 |
6.3× |
| ZSet (ZADD/ZRANGE/ZINCRBY/ZREM/ZREMRANGEBYRANK/BZPOPMIN) | ~19 | 3 |
6.3× |
Steady-state: ZADD on an existing zset, XADD on an existing stream, HSET
on an existing hash all hit the fast path. First-write and wrongType
cases pay the same as before.
## Self-review (CLAUDE.md 5 lenses)
1. **Data loss** — None. Read-only probe path; the slow-path fallback is
the unchanged `keyTypeAt`, so any branch that previously detected the
right type still does.
2. **Concurrency** — No new shared state. Each call is read-only against
the existing MVCC snapshot at `readTS`.
3. **Performance** — 6–9× seek reduction on the hit case (the steady
state for live keys), no extra seeks on the miss case (caller pays the
same ~19 seeks they would have without this PR).
4. **Data consistency** — TTL filter is applied identically to the slow
path; the fast path returns "found at readTS" only after the same
`applyTTLFilter` call. WrongType detection is preserved by slow-path
delegation when expected probes come back empty.
5. **Test coverage** — new `TestRedis_StreamCommandsRejectWrongType`
locks down the stream wrongType fall-through. Existing collection-family
wrongType tests (`TestRedis_HGET_WRONGTYPE`, etc.) lock down hash/set.
Existing collection round-trip tests cover the hit path; all now run
through `keyTypeAtExpect`.
## Test plan
- [x] `go test -race -run
"TestRedis_Stream|TestRedis_Hash|TestRedis_Z|TestRedis_HGET|TestRedis_HEXISTS|TestRedis_HMGET|TestRedis_HDEL|TestRedis_HLEN|TestRedis_HGETALL|TestRedis_BullMQ|TestRedis_BZPOPMIN|TestNextXAddID|TestXAddEnforce"
./adapter/...` — passes (146s)
- [x] `golangci-lint run ./adapter/...` — clean
- [ ] CI: full adapter test suite under -race
- [ ] CI: jepsen redis suite
## Follow-up
- Set / list / string / mixed-kind (validateExactSetKind, smembers,
pfcount, getdel, incr, ltrim, lindex, etc.) — same pattern, lower
production traffic, deferred.
@claude review3 files changed
Lines changed: 165 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2051 | 2051 | | |
2052 | 2052 | | |
2053 | 2053 | | |
2054 | | - | |
| 2054 | + | |
2055 | 2055 | | |
2056 | 2056 | | |
2057 | 2057 | | |
| |||
2506 | 2506 | | |
2507 | 2507 | | |
2508 | 2508 | | |
2509 | | - | |
| 2509 | + | |
2510 | 2510 | | |
2511 | 2511 | | |
2512 | 2512 | | |
| |||
2533 | 2533 | | |
2534 | 2534 | | |
2535 | 2535 | | |
2536 | | - | |
| 2536 | + | |
2537 | 2537 | | |
2538 | 2538 | | |
2539 | 2539 | | |
| |||
2564 | 2564 | | |
2565 | 2565 | | |
2566 | 2566 | | |
2567 | | - | |
| 2567 | + | |
2568 | 2568 | | |
2569 | 2569 | | |
2570 | 2570 | | |
| |||
2678 | 2678 | | |
2679 | 2679 | | |
2680 | 2680 | | |
2681 | | - | |
| 2681 | + | |
2682 | 2682 | | |
2683 | 2683 | | |
2684 | 2684 | | |
| |||
2801 | 2801 | | |
2802 | 2802 | | |
2803 | 2803 | | |
2804 | | - | |
| 2804 | + | |
2805 | 2805 | | |
2806 | 2806 | | |
2807 | 2807 | | |
| |||
2831 | 2831 | | |
2832 | 2832 | | |
2833 | 2833 | | |
2834 | | - | |
| 2834 | + | |
2835 | 2835 | | |
2836 | 2836 | | |
2837 | 2837 | | |
| |||
2950 | 2950 | | |
2951 | 2951 | | |
2952 | 2952 | | |
2953 | | - | |
| 2953 | + | |
2954 | 2954 | | |
2955 | 2955 | | |
2956 | 2956 | | |
| |||
3049 | 3049 | | |
3050 | 3050 | | |
3051 | 3051 | | |
3052 | | - | |
| 3052 | + | |
3053 | 3053 | | |
3054 | 3054 | | |
3055 | 3055 | | |
| |||
3271 | 3271 | | |
3272 | 3272 | | |
3273 | 3273 | | |
3274 | | - | |
| 3274 | + | |
3275 | 3275 | | |
3276 | 3276 | | |
3277 | 3277 | | |
| |||
3341 | 3341 | | |
3342 | 3342 | | |
3343 | 3343 | | |
3344 | | - | |
| 3344 | + | |
3345 | 3345 | | |
3346 | 3346 | | |
3347 | 3347 | | |
| |||
3511 | 3511 | | |
3512 | 3512 | | |
3513 | 3513 | | |
3514 | | - | |
| 3514 | + | |
3515 | 3515 | | |
3516 | 3516 | | |
3517 | 3517 | | |
| |||
3551 | 3551 | | |
3552 | 3552 | | |
3553 | 3553 | | |
3554 | | - | |
| 3554 | + | |
3555 | 3555 | | |
3556 | 3556 | | |
3557 | 3557 | | |
| |||
3599 | 3599 | | |
3600 | 3600 | | |
3601 | 3601 | | |
3602 | | - | |
| 3602 | + | |
3603 | 3603 | | |
3604 | 3604 | | |
3605 | 3605 | | |
| |||
3636 | 3636 | | |
3637 | 3637 | | |
3638 | 3638 | | |
3639 | | - | |
| 3639 | + | |
3640 | 3640 | | |
3641 | 3641 | | |
3642 | 3642 | | |
| |||
4022 | 4022 | | |
4023 | 4023 | | |
4024 | 4024 | | |
4025 | | - | |
| 4025 | + | |
4026 | 4026 | | |
4027 | 4027 | | |
4028 | 4028 | | |
| |||
4358 | 4358 | | |
4359 | 4359 | | |
4360 | 4360 | | |
4361 | | - | |
| 4361 | + | |
4362 | 4362 | | |
4363 | 4363 | | |
4364 | 4364 | | |
| |||
4584 | 4584 | | |
4585 | 4585 | | |
4586 | 4586 | | |
4587 | | - | |
| 4587 | + | |
4588 | 4588 | | |
4589 | 4589 | | |
4590 | 4590 | | |
| |||
4636 | 4636 | | |
4637 | 4637 | | |
4638 | 4638 | | |
4639 | | - | |
| 4639 | + | |
4640 | 4640 | | |
4641 | 4641 | | |
4642 | 4642 | | |
| |||
4972 | 4972 | | |
4973 | 4973 | | |
4974 | 4974 | | |
4975 | | - | |
| 4975 | + | |
4976 | 4976 | | |
4977 | 4977 | | |
4978 | 4978 | | |
| |||
5076 | 5076 | | |
5077 | 5077 | | |
5078 | 5078 | | |
5079 | | - | |
| 5079 | + | |
5080 | 5080 | | |
5081 | 5081 | | |
5082 | 5082 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
184 | 184 | | |
185 | 185 | | |
186 | 186 | | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
187 | 236 | | |
188 | 237 | | |
189 | 238 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
314 | 314 | | |
315 | 315 | | |
316 | 316 | | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 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 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
317 | 412 | | |
318 | 413 | | |
319 | 414 | | |
| |||
0 commit comments