diff options
author | antirez <antirez@gmail.com> | 2014-03-21 09:52:00 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2014-03-21 09:52:05 +0100 |
commit | 6972f18cbd1b71ebaf4a8f077ab79a59ccaccea2 (patch) | |
tree | ab0150e9dbedaa9064a28c883c3714c79c76692a | |
parent | 4d2e8fa189665e8e76040da9642ca89ef55fba10 (diff) | |
download | redis-6972f18cbd1b71ebaf4a8f077ab79a59ccaccea2.tar.gz |
Add test-lru.rb to utils.
This is a program useful to evaluate the Redis LRU algorithm behavior.
-rw-r--r-- | utils/lru/README | 13 | ||||
-rw-r--r-- | utils/lru/test-lru.rb | 112 |
2 files changed, 125 insertions, 0 deletions
diff --git a/utils/lru/README b/utils/lru/README new file mode 100644 index 000000000..288189e3e --- /dev/null +++ b/utils/lru/README @@ -0,0 +1,13 @@ +The test-lru.rb program can be used in order to check the behavior of the +Redis approximated LRU algorithm against the theoretical output of true +LRU algorithm. + +In order to use the program you need to recompile Redis setting the define +REDIS_LRU_CLOCK_RESOLUTION to 1, by editing redis.h. +This allows to execute the program in a fast way since the 1 ms resolution +is enough for all the objects to have a different enough time stamp during +the test. + +The program is executed like this: + + ruby test-lru.rb > /tmp/lru.html diff --git a/utils/lru/test-lru.rb b/utils/lru/test-lru.rb new file mode 100644 index 000000000..d4b0f88cf --- /dev/null +++ b/utils/lru/test-lru.rb @@ -0,0 +1,112 @@ +require 'rubygems' +require 'redis' + +r = Redis.new +r.config("SET","maxmemory","2000000") +r.config("SET","maxmemory-policy","allkeys-lru") +r.config("SET","maxmemory-samples",5) +r.config("RESETSTAT") +r.flushall + +puts <<EOF +<html> +<body> +<style> +.box { + width:5px; + height:5px; + float:left; + margin: 1px; +} + +.old { + border: 1px black solid; +} + +.new { + border: 1px green solid; +} + +.ex { + background-color: #666; +} +</style> +<pre> +EOF + +# Fill +oldsize = r.dbsize +id = 0 +while true + id += 1 + r.set(id,"foo") + newsize = r.dbsize + break if newsize == oldsize + oldsize = newsize +end + +inserted = r.dbsize +first_set_max_id = id +puts "#{r.dbsize} keys inserted" + +# Access keys sequencially + +puts "Access keys sequencially" +(1..first_set_max_id).each{|id| + r.get(id) +# sleep 0.001 +} + +# Insert more 50% keys. We expect that the new keys +half = inserted/2 +puts "Insert enough keys to evict half the keys we inserted" +add = 0 +while true + add += 1 + id += 1 + r.set(id,"foo") + break if r.info['evicted_keys'].to_i >= half +end + +puts "#{add} additional keys added." +puts "#{r.dbsize} keys in DB" + +# Check if evicted keys respect LRU +# We consider errors from 1 to N progressively more serious as they violate +# more the access pattern. + +errors = 0 +e = 1 +edecr = 1.0/(first_set_max_id/2) +(1..(first_set_max_id/2)).each{|id| + e -= edecr if e > 0 + e = 0 if e < 0 + if r.exists(id) + errors += e + end +} + +puts "#{errors} errors!" +puts "</pre>" + +# Generate the graphical representation +(1..id).each{|id| + # Mark first set and added items in a different way. + c = "box" + if id <= first_set_max_id + c << " old" + else + c << " new" + end + + # Add class if exists + c << " ex" if r.exists(id) + puts "<div class=\"#{c}\"></div>" +} + +# Close HTML page + +puts <<EOF +</body> +</html> +EOF |