130

My redis instance seems to being growing very large and I'd like to find out which of the multiple databases I have in there consumes how much memory. Redis' INFO command just shows me the total size and the number of keys per database which doesn't give me much insight... So any tools/ideas that give me more information when monitoring the redis server would be appreciated.

The Redis documentation doesn't show me any commands that can return the consumed memory of certain keys, so I guess if any buggy code would write a lot of "trash" to redis this could be really hard to find...

Marc Bollinger
  • 3,109
  • 2
  • 27
  • 32
Bernhard Vallant
  • 49,468
  • 20
  • 120
  • 148

14 Answers14

134

So my solution to my own problem: After playing around with redis-cli a bit longer I found out that DEBUG OBJECT <key> reveals something like the serializedlength of key, which was in fact something I was looking for...

For a whole database you need to aggregate all values for KEYS * which shouldn't be too difficult with a scripting language of your choice...

The bad thing is that redis.io doesn't really have a lot of information about DEBUG OBJECT.

slm
  • 15,396
  • 12
  • 109
  • 124
Bernhard Vallant
  • 49,468
  • 20
  • 120
  • 148
  • 1
    Is serialized length the size of the entire object, in bytes? – raffian Aug 17 '12 at 00:38
  • 20
    @BernhardVallant, thanks for answer. I went ahead and wrote a quick script that prints all the keys and their sizes in a human readable format. Thought I would share. :) https://gist.github.com/epicserve/5699837 – Brent O'Connor Jun 04 '13 at 01:44
  • 16
    The value of *serializedlength* is not about memory size! It is the size an objects would take when save to a RDB file on disk. Check the source code: https://github.com/antirez/redis/blob/4082c38a60eedd524c78ef48c1b241105f4ddc50/src/debug.c#L337-L343 and https://github.com/antirez/redis/blob/4082c38a60eedd524c78ef48c1b241105f4ddc50/src/rdb.c#L663-L671 – Hugo Lopes Tavares Jul 05 '15 at 17:01
  • there doesn't seem to be a way to get the size of the key or value or key-value in memory (Not the dumped size to disk) – Avba Mar 20 '18 at 15:40
  • This does not include the size of the key itself, only the value. – Aalex Gabi Mar 21 '18 at 10:33
  • 5
    FYI: don't bother trying anything with DEBUG on AWS ElastiCache Redis, https://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/ClientConfig.RestrictedCommands.html. Even found redis-cli --bigkeys would stall – sonjz Apr 12 '18 at 20:53
  • 1
    You can take script created by @BrentO'Connor and replace "debug object" by "memory usage". Works for ElasticCache where "debug" is disabled – Illidan Oct 12 '21 at 06:05
108

The solution from the comments deserves its own answer:

redis-cli --bigkeys
danronmoon
  • 3,814
  • 5
  • 34
  • 56
miracle2k
  • 29,597
  • 21
  • 65
  • 64
  • 5
    big keys is about the size of the _key_, not the size of the value stored .. so you could have a key of `a` with a 4GB value but this would not show up in bigkeys. (this is going by https://gist.github.com/michael-grunder/9257326 and https://docs.redislabs.com/latest/ri/memory-optimizations/use-smaller-keys/ ) – EoghanM Apr 24 '20 at 12:35
  • --bigkeys does an object scan and tells you by content, not just the key length – Mathieu Longtin May 16 '23 at 17:23
107

MEMORY USAGE key command gives you the number of bytes that a key and its value require to be stored in RAM.

The reported usage is the total of memory allocations for data and administrative overheads that a key its value require (source redis documentation)

dogfish
  • 2,646
  • 4
  • 21
  • 37
16

Take a look at this project it outputs some interesting stats about keyspaces based on regexs and prefixes. It uses the DEBUG OBJECT command and scans the db, identifying groups of keys and estimating the percentage of space they're taking up.

https://github.com/snmaynard/redis-audit

Output looks like this:

Summary  

---------------------------------------------------+--------------+-------------------+---------------------------------------------------  
Key                                                | Memory Usage | Expiry Proportion | Last Access Time                                    
---------------------------------------------------+--------------+-------------------+---------------------------------------------------  
notification_3109439                               | 88.14%       | 0.0%              | 2 minutes                               
user_profile_3897016                               | 11.86%       | 99.98%            | 20 seconds  
---------------------------------------------------+--------------+-------------------+---------------------------------------------------  

Or this this one: https://github.com/sripathikrishnan/redis-rdb-tools which does a full analysis on the entire keyspace by analyzing a dump.rdb file offline. This one works well also. It can give you the avg/min/max size for the entries in your db, and will even do it based on a prefix.

jumand
  • 872
  • 8
  • 17
10

You might find it very useful to sample Redis keys and group them by type. Salvatore has written a tool called redis-sampler that issues about 10000 RANDOMKEY commands followed by a TYPE on retrieved keys. In a matter of seconds, or minutes, you should get a fairly accurate view of the distribution of key types.

I've written an extension (unfortunately not anywhere open-source because it's work related), that adds a bit of introspection of key names via regexs that give you an idea of what kinds of application keys (according to whatever naming structure you're using), are stored in Redis. Combined with the more general output of redis-sampler, this should give you an extremely good idea of what's going on.

rlotun
  • 7,897
  • 4
  • 28
  • 23
6

You can also check the INFO command in redis to view the memory usage

$ redis-cli
127.0.0.1:6379> INFO memory
Abercrombie
  • 1,012
  • 2
  • 13
  • 22
  • 1
    this will provide overall memory info but not at the database level which OP is asking for. – Khatri Jun 29 '21 at 05:18
5

Perhaps you can do some introspection on the db file. The protocol is relatively simple (yet not well documented), so you could write a parser for it to determine which individual keys are taking up a lot of space.


New suggestions:

Have you tried using MONITOR to see what is being written, live? Perhaps you can find the issue with the data in motion.

Donald Miner
  • 38,889
  • 8
  • 95
  • 118
  • Seems to be interesting, but nevertheless I'my trying to find an easy way to monitor redis' memory consumption on the server... Examining the dump seems to be more practicable for debugging to me, not too mention that the dump is a few gigs now! – Bernhard Vallant Oct 03 '11 at 23:47
  • You should ask the redis mailing list. I'm really interesting in hearing the "best" answer for this. – Donald Miner Oct 04 '11 at 02:26
  • Well have already tried `INFO` and `MONITOR`, but may main problem is, that when not watching redis grew really big... – Bernhard Vallant Oct 04 '11 at 07:49
  • Ok i posted it to their mailing list, but found an answer on my own also... See below! – Bernhard Vallant Oct 04 '11 at 14:28
  • re. introspection on db file - I wrote a script to parse dump.rdb files and output a csv file reporting the approximate memory used by each key. See https://github.com/sripathikrishnan/redis-rdb-tools – Sripathi Krishnan Apr 02 '12 at 05:56
3

Quick and dirty if you know the prefix you can sum the set of keys:

echo "keys userfeed*" | redis-cli -h 10.168.229.48 | xargs -I{} echo "debug object {}" | redis-cli -h 10.168.229.48 | awk '{print $5}' | cut -
d: -f2 | awk '{s+=$1} END {print s}'

This give the size in bytes. Remember this is "serialized length" not size in memory.

To get size in memory in bytes:

echo "keys op*" | redis-cli -h 10.168.229.48 | xargs -I{} echo "memory usage {} samples 0" | redis-cli -h 10.168.229.48 | awk '{s+=$1} END {pr
int s}'
lucaswxp
  • 2,031
  • 5
  • 23
  • 34
2

I usually prefer the key sampling method to troubleshoot such scenarios.

redis-cli -p 6379 -n db_number --bigkeys

Eg:-

redis-cli -p 6370 -n 0 --bigkeys

anrajme
  • 787
  • 8
  • 6
  • 1
    Why is this the "key sampling" method? I find it very limited as it only shows the tip of the iceberg. – MrR Jul 15 '20 at 10:50
2

lua one-liner

eval "local sum = 0; local matches = redis.call('KEYS', '<pattern>'); for _,key in ipairs(matches) do local val = redis.call('memory', 'usage', key); sum = sum + tonumber(val) end return sum" 0
Rudolf Yurgenson
  • 603
  • 6
  • 12
2

You're Right the Redis documentation doesn't show any commands that can return the consumed memory of certain keys. Redis does not provide an out-of-the-box command to retrieve memory consumption per database or per key. But don't worry there are many ways

  1. A very simple solution :

Use the redis-cli cmd tool with --bigkeys see below cmd

redis-cli --bigkeys
  1. You can use the MEMORY USAGE cmd that returns the number of bytes consumed by a key see below cmd.

    redis-cli MEMORY USAGE <your-redis-key>

  2. We have best solution to use external tools to monitor and analyze Redis instance.

Use RedisInsight A GUI-based Redis management tool that allows to inspect and manage Redis instances, including memory analysis.

See the image I use RedisInsight to monitor db. RedisInsight GUI is user-friendly

enter image description here

These are the methods, that I used to identify the memory consumption patterns in Redis instance and track down any problematic keys when I'm working. and I hope these methods assist you too.

Muhammad Amir
  • 2,326
  • 1
  • 12
  • 13
1

You can use .net application https://github.com/abhiyx/RedisSizeCalculator to calculate the size of redis key,

Please feel free to give your feedback for the same

abhi
  • 1,059
  • 9
  • 19
0

How about

redis-cli get KEYNAME | wc -c  
Syscall
  • 19,327
  • 10
  • 37
  • 52
Ed Greenberg
  • 209
  • 3
  • 12
0

One-liner. All redis keys and corresponding used memory.

redis-cli keys "*" | while read line; do echo -n "$line: "; redis-cli memory usage $line; done
Syscall
  • 19,327
  • 10
  • 37
  • 52