diff options
author | Harkrishn Patro <harkrisp@amazon.com> | 2022-12-06 22:26:56 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-07 08:26:56 +0200 |
commit | c0267b3fa5808df475dec83c956b9a2bec112b90 (patch) | |
tree | fd3913a9b0d1fe8cbb08a0618ea719db886a9eb7 /tests | |
parent | 8a315fc285fc54c678b97107a02ee1627f2c1ebf (diff) | |
download | redis-c0267b3fa5808df475dec83c956b9a2bec112b90.tar.gz |
Optimize client memory usage tracking operation while client eviction is disabled (#11348)
## Issue
During the client input/output buffer processing, the memory usage is
incrementally updated to keep track of clients going beyond a certain
threshold `maxmemory-clients` to be evicted. However, this additional
tracking activity leads to unnecessary CPU cycles wasted when no
client-eviction is required. It is applicable in two cases.
* `maxmemory-clients` is set to `0` which equates to no client eviction
(applicable to all clients)
* `CLIENT NO-EVICT` flag is set to `ON` which equates to a particular
client not applicable for eviction.
## Solution
* Disable client memory usage tracking during the read/write flow when
`maxmemory-clients` is set to `0` or `client no-evict` is `on`.
The memory usage is tracked only during the `clientCron` i.e. it gets
periodically updated.
* Cleanup the clients from the memory usage bucket when client eviction
is disabled.
* When the maxmemory-clients config is enabled or disabled at runtime,
we immediately update the memory usage buckets for all clients (tested
scanning 80000 took some 20ms)
Benchmark shown that this can improve performance by about 5% in
certain situations.
Co-authored-by: Oran Agra <oran@redislabs.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/client-eviction.tcl | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/tests/unit/client-eviction.tcl b/tests/unit/client-eviction.tcl index cd6ee1a6e..ca6d9020f 100644 --- a/tests/unit/client-eviction.tcl +++ b/tests/unit/client-eviction.tcl @@ -140,7 +140,7 @@ start_server {} { set temp_maxmemory_clients 200000 r config set maxmemory-clients $temp_maxmemory_clients - # Append watched keys until list maxes out maxmemroy clients and causes client eviction + # Append watched keys until list maxes out maxmemory clients and causes client eviction catch { for {set j 0} {$j < $temp_maxmemory_clients} {incr j} { $rr watch $j @@ -467,7 +467,7 @@ start_server {} { start_server {} { test "evict clients in right order (large to small)" { # Note that each size step needs to be at least x2 larger than previous step - # because of how the client-eviction size bucktting works + # because of how the client-eviction size bucketing works set sizes [list [kb 128] [mb 1] [mb 3]] set clients_per_size 3 r client setname control @@ -531,5 +531,52 @@ start_server {} { } {} {needs:debug} } +start_server {} { + foreach type {"client no-evict" "maxmemory-clients disabled"} { + r flushall + r client no-evict on + r config set maxmemory-clients 0 + + test "client total memory grows during $type" { + r setrange k [mb 1] v + set rr [redis_client] + $rr client setname test_client + if {$type eq "client no-evict"} { + $rr client no-evict on + r config set maxmemory-clients 1 + } + $rr deferred 1 + + # Fill output buffer in loop without reading it and make sure + # the tot-mem of client has increased (OS buffers didn't swallow it) + # and eviction not occurring. + while {true} { + $rr get k + $rr flush + after 10 + if {[client_field test_client tot-mem] > [mb 10]} { + break + } + } + + # Trigger the client eviction, by flipping the no-evict flag to off + if {$type eq "client no-evict"} { + $rr client no-evict off + } else { + r config set maxmemory-clients 1 + } + + # wait for the client to be disconnected + wait_for_condition 5000 50 { + ![client_exists test_client] + } else { + puts [r client list] + fail "client was not disconnected" + } + $rr close + } + } } +} ;# tags + |