Skip to content

Increase latency for big list test in defrag#2421

Merged
madolson merged 3 commits into
valkey-io:unstablefrom
sungming2:fix-big-list-defrag
Aug 7, 2025
Merged

Increase latency for big list test in defrag#2421
madolson merged 3 commits into
valkey-io:unstablefrom
sungming2:fix-big-list-defrag

Conversation

@sungming2

Copy link
Copy Markdown
Contributor

Across multiple runs of the big list test in defrag, the latency check is tripping because the maximum observed defrag cycle latency occasionally spikes above our 5 ms limit. While most cycles complete in just a few milliseconds, rare slowdowns push some cycles into the double digit millisecond range, so a 5 ms hard cap is too aggressive for stable testing.

/runtest --verbose --tls --single unit/memefficiency --only '/big list' --accurate --loop --fastfail
[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 12 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 21 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 25 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 17 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

Signed-off-by: Seungmin Lee <sungming@amazon.com>
@codecov

codecov Bot commented Aug 4, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.53%. Comparing base (3b12132) to head (18a59ae).
⚠️ Report is 26 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #2421      +/-   ##
============================================
+ Coverage     71.51%   71.53%   +0.02%     
============================================
  Files           123      125       +2     
  Lines         67454    69214    +1760     
============================================
+ Hits          48239    49513    +1274     
- Misses        19215    19701     +486     

see 30 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sungming2 sungming2 force-pushed the fix-big-list-defrag branch from e0c1ba0 to d8eed61 Compare August 4, 2025 10:22
@enjoy-binbin enjoy-binbin added the run-extra-tests Run extra tests on this PR (Runs all tests from daily except valgrind and RESP) label Aug 4, 2025

@zuiderkwast zuiderkwast left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sungming2 sungming2 marked this pull request as ready for review August 4, 2025 15:54

@hpatro hpatro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tagging @JimB123 to check if he has anything to add to this.

@madolson

madolson commented Aug 4, 2025

Copy link
Copy Markdown
Member

Do we understand what the rare slow downs are? If it's related to the system (perhaps valkey-server is getting descheduled) then I would expect every test to need this latency increase. If it's specific to just the lists, we probably should investigate that, since it's probably some type of bug.

@sungming2

Copy link
Copy Markdown
Contributor Author

Let me check other tests too

@zuiderkwast

Copy link
Copy Markdown
Contributor

Fixes #2205?

@zuiderkwast

Copy link
Copy Markdown
Contributor

Do we understand what the rare slow downs are?

According to #2398 (comment) (and a linked Redis issue) it can be related to kernel versions. A kernel mitigation for some CVE. @arkamar might be able to explain more...(?)

@sungming2

Copy link
Copy Markdown
Contributor Author

According to #2398 (comment) (and a linked Redis issue) it can be related to kernel versions. A kernel mitigation for some CVE. @arkamar might be able to explain more...(?)

I am not sure it's specific to the OS/kernel version because I was able to get above latency on both Ubuntu 20.04 and 24.04

@sungming2

sungming2 commented Aug 4, 2025

Copy link
Copy Markdown
Contributor Author
  • big hash
[err]: Active Defrag big hash: standalone in tests/unit/memefficiency.tcl
Expected 12 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big hash: standalone in tests/unit/memefficiency.tcl
Expected 18 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)
  • big set
[err]: Active Defrag big set: standalone in tests/unit/memefficiency.tcl
Expected 16 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

Test error (last server port:23623, log:./tests/tmp/server.152762.13/stdout), test will exit now
[err]: Active Defrag big set: standalone in tests/unit/memefficiency.tcl
Expected 12 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
  • big zset

[err]: Active Defrag big zset: standalone in tests/unit/memefficiency.tcl
Expected 24 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big zset: standalone in tests/unit/memefficiency.tcl
Expected 16 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

Can we consider increasing the default limit latency to 30 40?

# latency <ms> - optional, verifies the latency to a ms target (default 5)
proc perform_defrag_test {name args} {
set opts(latency) 5

@zuiderkwast

Copy link
Copy Markdown
Contributor

Can we consider increasing the default limit latency to 30?

Yes, good idea.

Signed-off-by: Seungmin Lee <sungming@amazon.com>
@madolson

madolson commented Aug 4, 2025

Copy link
Copy Markdown
Member

According to #2398 (comment) (and a linked Redis issue) it can be related to kernel versions. A kernel mitigation for some CVE. @arkamar might be able to explain more...(?)

This doesn't seem related. The original issue that was identified by arkamar is for timeouts, where as this is just taking slightly longer times.

@madolson

madolson commented Aug 4, 2025

Copy link
Copy Markdown
Member

Yes, good idea.

Setting it to 30ms almost defeats the purpose of the latency testing. The goal was to verify that active defragmentation isn't introducing latency spikes, but it seems like it is. Maybe we should allow 1 data point above the threshold?

@sungming2

Copy link
Copy Markdown
Contributor Author

Maybe we should allow 1 data point above the threshold?

I think that is also good idea but IMO, allowing 1 spike might not generalize across machines, environments, or workloads. Also, future contributors may misunderstand or misuse the logic (e.g., tolerating 1 or 2..), and if a single spike exceeds a drastically high value such as 1 second, it could still be allowed under this rule and go undetected

@madolson

madolson commented Aug 4, 2025

Copy link
Copy Markdown
Member

Maybe instead we could add a debug option to use clock_gettime(CLOCK_PROCESS_CPUTIME_ID) for testing? This should not include time when the process isn't being scheduled, which should hopefully remove some of the edge case times.

@sungming2

Copy link
Copy Markdown
Contributor Author

We are using the latency data reported by the server via the LATENCY command, which internally measures duration. Based on the implementation (defrag.c#L1165-L1190), I believe this provides sufficiently accurate duration. I also double checked the source of the latency, and it is coming from active-defrag-cycle, not while-blocked-cron

proc validate_latency {limit_ms} {
if {!$::no_latency} {
set max_latency 0
foreach event [r latency latest] {
lassign $event eventname time latency max
if {$eventname == "active-defrag-cycle" || $eventname == "while-blocked-cron"} {
set max_latency $max
}
}
if {$::verbose} {
puts "Validating max latency ($max_latency) is LT $limit_ms"
if {$max_latency > 0} {
puts [r latency latest]
puts [r latency history active-defrag-cycle]
puts [r latency history while-blocked-cron]
}
}
assert {$max_latency <= $limit_ms}
}
}

@zuiderkwast

Copy link
Copy Markdown
Contributor

There may be other causes of latency spikes, such as synchronous IO, that also affect these tests? Such as

@madolson

madolson commented Aug 5, 2025

Copy link
Copy Markdown
Member

There may be other causes of latency spikes, such as synchronous IO, that also affect these tests? Such as

I have a suspicion that it's related to the process being interrupted by the either the guest or host OS. The time will keep ticking up in those cases. We shouldn't be doing any synchronous IO in these tests.

@zuiderkwast

Copy link
Copy Markdown
Contributor

I have a suspicion that it's related to the process being interrupted by the either the guest or host OS.

If this is true, we can't really do much about it, can we? Let's merge this PR for now to unflake the tests?

@madolson

madolson commented Aug 5, 2025

Copy link
Copy Markdown
Member

If this is true, we can't really do much about it, can we? Let's merge this PR for now to unflake the tests?

I suggested we might be able to use the processor clock to actually track time used by the process. If that doesn't work, I think we should remove the latency check and create an issue for later.

@sungming2

Copy link
Copy Markdown
Contributor Author

I am checking the cpu clock, will get the result soon

@sungming2

Copy link
Copy Markdown
Contributor Author

I tested with CLOCK_PROCESS_CPUTIME_ID and other options like CLOCK_MONOTONIC, but the latency spikes still appear:

[err]: Active Defrag big hash: standalone in tests/unit/memefficiency.tcl
Expected 21 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)
[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 8 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)
[err]: Active Defrag big set: standalone in tests/unit/memefficiency.tcl
Expected 10 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

To investigate further, I wrote a simple loop to compare the timing behavior across different clocks, CLOCK_PROCESS_CPUTIME_ID sometimes takes longer than others:

gettimeofday             : 1067362 us
CLOCK_REALTIME           : 1052658 us
CLOCK_MONOTONIC          : 1062182 us
CLOCK_PROCESS_CPUTIME_ID : 1073927 us
CLOCK_THREAD_CPUTIME_ID  : 1057760 us

I found similar issues from online indicating that CLOCK_PROCESS_CPUTIME_ID incurs more overhead, as it queries the scheduler subsystem (via syscall) for fine grained/per thread/process CPU usage. This makes it sometimes more expensive than wall time clocks.

@madolson

madolson commented Aug 7, 2025

Copy link
Copy Markdown
Member

I found similar issues from online indicating that CLOCK_PROCESS_CPUTIME_ID incurs more overhead, as it queries the scheduler subsystem (via syscall) for fine grained/per thread/process CPU usage. This makes it sometimes more expensive than wall time clocks.

What you showed is all less than 1% differences, so I don't think that is causing the spike (the spike is on the order of 10000us) So, it seems like we still aren't sure what is causing the issue :/

I'm OK closing this. I'll make an issue to track it, and then we can merge this. EDIT: new issue #2444

Comment thread tests/unit/memefficiency.tcl
Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
@madolson madolson merged commit 70d336d into valkey-io:unstable Aug 7, 2025
59 of 60 checks passed
@sungming2 sungming2 self-assigned this Aug 8, 2025
allenss-amazon pushed a commit to allenss-amazon/valkey-core that referenced this pull request Aug 19, 2025
Across multiple runs of the big list test in defrag, the latency check
is tripping because the maximum observed defrag cycle latency
occasionally spikes above our 5 ms limit. While most cycles complete in
just a few milliseconds, rare slowdowns push some cycles into the double
digit millisecond range, so a 5 ms hard cap is too aggressive for stable
testing.

```
/runtest --verbose --tls --single unit/memefficiency --only '/big list' --accurate --loop --fastfail
```

```
[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 12 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 21 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 25 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

[err]: Active Defrag big list: standalone in tests/unit/memefficiency.tcl
Expected 17 <= 5 (context: type proc line 18 cmd {assert {$max_latency <= $limit_ms}} proc ::validate_latency level 1)
(Fast fail: test will exit now)

```

---------

Signed-off-by: Seungmin Lee <sungming@amazon.com>
Co-authored-by: Seungmin Lee <sungming@amazon.com>
madolson pushed a commit that referenced this pull request Sep 2, 2025
…40 (#2574)

Delete the out-of-date comment explaining why changed latency from 5 to
40 in #2421 , which is a leftover of #2553

Signed-off-by: Alina Liu <liusalisa6363@gmail.com>
rjd15372 pushed a commit to rjd15372/valkey that referenced this pull request Sep 19, 2025
…40 (valkey-io#2574)

Delete the out-of-date comment explaining why changed latency from 5 to
40 in valkey-io#2421 , which is a leftover of valkey-io#2553

Signed-off-by: Alina Liu <liusalisa6363@gmail.com>
rjd15372 pushed a commit that referenced this pull request Sep 23, 2025
…40 (#2574)

Delete the out-of-date comment explaining why changed latency from 5 to
40 in #2421 , which is a leftover of #2553

Signed-off-by: Alina Liu <liusalisa6363@gmail.com>
hpatro pushed a commit to hpatro/valkey that referenced this pull request Oct 3, 2025
…40 (valkey-io#2574)

Delete the out-of-date comment explaining why changed latency from 5 to
40 in valkey-io#2421 , which is a leftover of valkey-io#2553

Signed-off-by: Alina Liu <liusalisa6363@gmail.com>
Signed-off-by: Harkrishn Patro <harkrisp@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-extra-tests Run extra tests on this PR (Runs all tests from daily except valgrind and RESP)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants