What is the easiest way to find the biggest objects in Redis?

Redis

Redis Problem Overview


I have a 20GB+ rdb dump in production. I suspect there's a specific set of keys bloating it. I'd like to have a way to always spot the first 100 biggest objects from static dump analysis or ask it to the server itself, which by the way has ove 7M objects.

Dump analysis tools like rdbtools are not helpful in this (I think) really common use case!

I was thinking to write a script and iterate the whole keyset with "redis-cli debug object", but I have the feeling there must be some tool I'm missing.

Redis Solutions


Solution 1 - Redis

An option was added to redis-cli: redis-cli --bigkeys

Sample output based on https://gist.github.com/michael-grunder/9257326

$ ./redis-cli --bigkeys
 
# Press ctrl+c when you have had enough of it... :)
# You can use -i 0.1 to sleep 0.1 sec every 100 sampled keys
# in order to reduce server load (usually not needed).
 
Biggest string so far: day:uv:483:1201737600, size: 2
Biggest string so far: day:pv:2013:1315267200, size: 3
Biggest string so far: day:pv:3:1290297600, size: 5
Biggest zset so far: day:topref:2734:1289433600, size: 3
Biggest zset so far: day:topkw:2236:1318723200, size: 7
Biggest zset so far: day:topref:651:1320364800, size: 20
Biggest string so far: uid:3467:auth, size: 32
Biggest set so far: uid:3029:allowed, size: 1
Biggest list so far: last:175, size: 51
    

-------- summary -------

Sampled 329 keys in the keyspace!
Total key length in bytes is 15172 (avg len 46.12)

Biggest   list found 'day:uv:483:1201737600' has 5235597 items
Biggest    set found 'day:uvx:555:1201737600' has 47 members
Biggest   hash found 'day:uvy:131:1201737600' has 2888 fields
Biggest   zset found 'day:uvz:777:1201737600' has 1000 members

0 strings with 0 bytes (00.00% of keys, avg size 0.00)
19 lists with 5236744 items (05.78% of keys, avg size 275618.11)
50 sets with 112 members (15.20% of keys, avg size 2.24)
250 hashs with 6915 fields (75.99% of keys, avg size 27.66)
10 zsets with 1294 members (03.04% of keys, avg size 129.40)

Solution 2 - Redis

redis-rdb-tools does have a memory report that does exactly what you need. It generates a CSV file with memory used by every key. You can then sort it and find the Top x keys.

There is also an experimental memory profiler that started to do what you need. Its not yet complete, and so isn't documented. But you can try it - https://github.com/sripathikrishnan/redis-rdb-tools/tree/master/rdbtools/cli. And of course, I'd encourage you to contribute as well!

Disclaimer: I am the author of this tool.

Solution 3 - Redis

I am pretty new to bash scripting. I came out with this:

for line in $(redis-cli keys '*' | awk '{print $1}'); do echo `redis-cli DEBUG OBJECT $line | awk '{print $5}' | sed 's/serializedlength://g'` $line; done; | sort -h

This script

  • Lists all the key with redis-cli keys "*"
  • Gets size with redis-cli DEBUG OBJECT
  • sorts the script based on the name prepend with the size

This may be very slow due to the fact that bash is looping through every single redis key. You have 7m keys you may need to cache the out put of the keys to a file.

Solution 4 - Redis

If you have keys that follow this pattern "A:B" or "A:B:*", I wrote a tool that analyzes both existing content as well as monitors for things such as hit rate, number of gets/sets, network traffic, lifetime, etc. The output is similar to the one below.

https://github.com/alexdicianu/redis_toolkit

$ ./redis-toolkit report -type memory -name NAME
+----------------------------------------+----------+-----------+----------+
|                     KEY                | NR  KEYS | SIZE (MB) | SIZE (%) |
+----------------------------------------+----------+-----------+----------+
| posts:*                                |      500 |      0.56 |     2.79 |
| post_meta:*                            |      440 |     18.48 |    92.78 |
| terms:*                                |      192 |      0.12 |     0.63 |
| options:*                              |      109 |      0.52 |     2.59 |

Solution 5 - Redis

Try redis-memory-analyzer - a console tool to scan Redis key space in real time and aggregate memory usage statistic by key patterns. You may use this tools without maintenance on production servers. It shows you detailed statistics about each key pattern in your Redis serve.

Also you can scan Redis db by all or selected Redis types such as "string", "hash", "list", "set", "zset". Matching pattern also supported.

RMA also try to discern key names by patterns, for example if you have keys like 'user:100' and 'user:101' application would pick out common pattern 'user:*' in output so you can analyze most memory distressed data in your instance.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsscarduzioView Question on Stackoverflow
Solution 1 - RedisFrank FarmerView Answer on Stackoverflow
Solution 2 - RedisSripathi KrishnanView Answer on Stackoverflow
Solution 3 - RedisTrent EarlView Answer on Stackoverflow
Solution 4 - RedisAlex DicianuView Answer on Stackoverflow
Solution 5 - RedisNick BondarenkoView Answer on Stackoverflow