summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2020-12-06 14:51:22 +0200
committerOran Agra <oran@redislabs.com>2021-01-12 16:25:37 +0200
commitf2f57eb44fb0c2810432f42bba586eea2a93569c (patch)
treefac4bbf54f951bca7f59a38659fc27c93560b5f1 /tests
parent8119259bb6ff3ab75995ba2f51ca4884dabb0540 (diff)
downloadredis-f2f57eb44fb0c2810432f42bba586eea2a93569c.tar.gz
prevent client tracking from causing feedback loop in performEvictions (#8100)
When client tracking is enabled signalModifiedKey can increase memory usage, this can cause the loop in performEvictions to keep running since it was measuring the memory usage impact of signalModifiedKey. The section that measures the memory impact of the eviction should be just on dbDelete, excluding keyspace notification, client tracking, and propagation to AOF and replicas. This resolves part of the problem described in #8069 p.s. fix took 1 minute, test took about 3 hours to write. (cherry picked from commit c4fdf09c0584a3cee32b92f01b7958c72776aedc)
Diffstat (limited to 'tests')
-rw-r--r--tests/support/redis.tcl7
-rw-r--r--tests/unit/maxmemory.tcl50
2 files changed, 57 insertions, 0 deletions
diff --git a/tests/support/redis.tcl b/tests/support/redis.tcl
index 566750c0d..3098a99f8 100644
--- a/tests/support/redis.tcl
+++ b/tests/support/redis.tcl
@@ -232,13 +232,20 @@ proc ::redis::redis_read_line fd {
string trim [gets $fd]
}
+proc ::redis::redis_read_null fd {
+ gets $fd
+ return {}
+}
+
proc ::redis::redis_read_reply {id fd} {
set type [read $fd 1]
switch -exact -- $type {
+ _ {redis_read_null $fd}
: -
+ {redis_read_line $fd}
- {return -code error [redis_read_line $fd]}
$ {redis_bulk_read $fd}
+ > -
* {redis_multi_bulk_read $id $fd}
% {redis_read_map $id $fd}
default {
diff --git a/tests/unit/maxmemory.tcl b/tests/unit/maxmemory.tcl
index 0f64ddc18..218f7bb1d 100644
--- a/tests/unit/maxmemory.tcl
+++ b/tests/unit/maxmemory.tcl
@@ -241,3 +241,53 @@ test_slave_buffers {slave buffer are counted correctly} 1000000 10 0 1
# test again with fewer (and bigger) commands without pipeline, but with eviction
test_slave_buffers "replica buffer don't induce eviction" 100000 100 1 0
+start_server {tags {"maxmemory"}} {
+ test {client tracking don't cause eviction feedback loop} {
+ r config set maxmemory 0
+ r config set maxmemory-policy allkeys-lru
+
+ # 10 clients listening on tracking messages
+ set clients {}
+ for {set j 0} {$j < 10} {incr j} {
+ lappend clients [redis_deferring_client]
+ }
+ foreach rd $clients {
+ $rd HELLO 3
+ $rd read ; # Consume the HELLO reply
+ $rd CLIENT TRACKING on
+ $rd read ; # Consume the CLIENT reply
+ }
+
+ # populate 300 keys, with long key name and short value
+ for {set j 0} {$j < 300} {incr j} {
+ set key $j[string repeat x 1000]
+ r set $key x
+
+ # for each key, enable caching for this key
+ foreach rd $clients {
+ $rd get $key
+ $rd read
+ }
+ }
+
+ # set the memory limit which will cause a few keys to be evicted
+ # we need to make sure to evict keynames of a total size of more than
+ # 16kb since the (PROTO_REPLY_CHUNK_BYTES), only after that the
+ # invalidation messages have a chance to trigger further eviction.
+ set used [s used_memory]
+ set limit [expr {$used - 40000}]
+ r config set maxmemory $limit
+
+ # make sure some eviction happened
+ set evicted [s evicted_keys]
+ if {$::verbose} { puts "evicted: $evicted" }
+ assert_range $evicted 10 50
+ foreach rd $clients {
+ $rd read ;# make sure we have some invalidation message waiting
+ $rd close
+ }
+
+ # make sure we didn't drain the database
+ assert_range [r dbsize] 200 300
+ }
+}