Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid buffer copies in RedisStateMachine #2174

Closed
wants to merge 3 commits into from

Conversation

jeffreye
Copy link

@jeffreye jeffreye commented Aug 1, 2022

Make sure that:

  • You have read the contribution guidelines.
  • You have created a feature request first to discuss your contribution intent. Please reference the feature request ticket number in the pull request.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.

see also #2173

Here are some performance results

db.PIPELINE GET.requests - 10000
db.PIPELINE GET.size - 128
db.clients - 1
db.loop - 5
Loaded keys - 1918458
Connections Formed
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 2.35
Avg (ms) - 2.6
P90 (ms) - 3.28
P95 (ms) - 3.81
P99 (ms) - 7.24
OPS - 49167
Time Taken (s) for loop 0 is - 26.95
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 2.3
Avg (ms) - 2.84
P90 (ms) - 3.12
P95 (ms) - 3.56
P99 (ms) - 6.65
OPS - 45027
Time Taken (s) for loop 1 is - 29.26
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 2.33
Avg (ms) - 2.52
P90 (ms) - 3.16
P95 (ms) - 3.55
P99 (ms) - 6.01
OPS - 50826
Time Taken (s) for loop 2 is - 25.97
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 2.32
Avg (ms) - 2.49
P90 (ms) - 3.13
P95 (ms) - 3.47
P99 (ms) - 5.8
OPS - 51426
Time Taken (s) for loop 3 is - 25.65
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 2.34
Avg (ms) - 2.54
P90 (ms) - 3.18
P95 (ms) - 3.65
P99 (ms) - 6.55
OPS - 50337
Time Taken (s) for loop 4 is - 26.2

db.PIPELINE GET.requests - 10000
db.PIPELINE GET.size - 128
db.clients - 1
db.loop - 5
Loaded keys - 1918458
Connections Formed
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 1.81
Avg (ms) - 2.08
P90 (ms) - 2.55
P95 (ms) - 3.02
P99 (ms) - 6.02
OPS - 61661
Time Taken (s) for loop 0 is - 21.69
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 1.76
Avg (ms) - 1.93
P90 (ms) - 2.24
P95 (ms) - 2.56
P99 (ms) - 4.48
OPS - 66164
Time Taken (s) for loop 1 is - 20.18
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 1.77
Avg (ms) - 1.96
P90 (ms) - 2.28
P95 (ms) - 2.69
P99 (ms) - 5.2
OPS - 65170
Time Taken (s) for loop 2 is - 20.44
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 1.75
Avg (ms) - 1.93
P90 (ms) - 2.22
P95 (ms) - 2.57
P99 (ms) - 5.09
OPS - 66303
Time Taken (s) for loop 3 is - 20.07
PIPELINE GET Performance
Total Req - 1280000
P50 (ms) - 1.77
Avg (ms) - 1.94
P90 (ms) - 2.25
P95 (ms) - 2.61
P99 (ms) - 4.81
OPS - 65856
Time Taken (s) for loop 4 is - 20.19

@jeffreye jeffreye marked this pull request as ready for review August 4, 2022 17:39
@mp911de
Copy link
Collaborator

mp911de commented Oct 7, 2022

Thanks a lot. Care to run the JMH benchmark RedisStateMachineBenchmark before and after the change? This is an interesting change that we would consider for the next minor release.

@mp911de mp911de added the type: feature A new feature label Oct 7, 2022
@mp911de mp911de linked an issue Oct 7, 2022 that may be closed by this pull request
@jeffreye
Copy link
Author

After

# JMH version: 1.21
# VM version: JDK 1.8.0_332, OpenJDK 64-Bit Server VM, 25.332-b09
# VM options: -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=51975:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 2 s per iteration, ***WARNING: The timeout might be too low!***
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: io.lettuce.core.protocol.RedisStateMachineBenchmark.measureDecode

# Run progress: 0.00% complete, ETA 00:01:40
# Fork: 1 of 1
# Warmup Iteration   1: 211.223 ns/op
# Warmup Iteration   2: 211.419 ns/op
# Warmup Iteration   3: 209.558 ns/op
# Warmup Iteration   4: 209.059 ns/op
# Warmup Iteration   5: 206.593 ns/op
Iteration   1: 206.514 ns/op
Iteration   2: 207.120 ns/op
Iteration   3: 206.357 ns/op
Iteration   4: 206.831 ns/op
Iteration   5: 206.158 ns/op


Result "io.lettuce.core.protocol.RedisStateMachineBenchmark.measureDecode":
  206.596 ±(99.9%) 1.474 ns/op [Average]
  (min, avg, max) = (206.158, 206.596, 207.120), stdev = 0.383
  CI (99.9%): [205.122, 208.070] (assumes normal distribution)


# Run complete. Total time: 00:01:42

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark                                 Mode  Cnt    Score   Error  Units
RedisStateMachineBenchmark.measureDecode  avgt    5  206.596 ± 1.474  ns/op

Process finished with exit code 0

Before

# JMH version: 1.21
# VM version: JDK 1.8.0_332, OpenJDK 64-Bit Server VM, 25.332-b09
# VM options: -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=52094:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 2 s per iteration, ***WARNING: The timeout might be too low!***
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: io.lettuce.core.protocol.RedisStateMachineBenchmark.measureDecode

# Run progress: 0.00% complete, ETA 00:01:40
# Fork: 1 of 1
# Warmup Iteration   1: 288.640 ns/op
# Warmup Iteration   2: 284.225 ns/op
# Warmup Iteration   3: 277.962 ns/op
# Warmup Iteration   4: 277.098 ns/op
# Warmup Iteration   5: 272.736 ns/op
Iteration   1: 275.259 ns/op
Iteration   2: 275.443 ns/op
Iteration   3: 279.652 ns/op
Iteration   4: 275.741 ns/op
Iteration   5: 271.997 ns/op


Result "io.lettuce.core.protocol.RedisStateMachineBenchmark.measureDecode":
  275.618 ±(99.9%) 10.467 ns/op [Average]
  (min, avg, max) = (271.997, 275.618, 279.652), stdev = 2.718
  CI (99.9%): [265.151, 286.086] (assumes normal distribution)


# Run complete. Total time: 00:01:42

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark                                 Mode  Cnt    Score    Error  Units
RedisStateMachineBenchmark.measureDecode  avgt    5  275.618 ± 10.467  ns/op

Process finished with exit code 0

Summary:
275.618 ± 10.467 ns/op -> 206.596 ± 1.474 ns/op

As the payload size in this benchmark is too small, it may not reflect the reality in production environment. This change will reduce memory pressure so it will also help GC and have bigger impact to the application.

@mp911de mp911de changed the title zero-copy buffer reader -- slice buffer Avoid buffer copies in RedisStateMachine Nov 23, 2022
@mp911de mp911de modified the milestones: 7.x, 6.3 Nov 23, 2022
mp911de pushed a commit that referenced this pull request Nov 23, 2022
mp911de added a commit that referenced this pull request Nov 23, 2022
Reintroduce deprecated constructor.

Original pull request: #2174
@mp911de
Copy link
Collaborator

mp911de commented Nov 23, 2022

Thank you for your contribution. That's merged and polished now.

@mp911de mp911de closed this Nov 23, 2022
@jeffreye
Copy link
Author

Hi @mp911de what's the expected date to release this change? This offers great performance improvement and we need them very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature A new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Avoid buffer copies in RedisStateMachine
2 participants