The method in Redis to count the various data sizes

  • 2020-05-07 20:38:36
  • OfStack

If the MySQL database is large, we can easily find out which tables are taking up space. But if Redis has a lot of memory, it's not easy to figure out which keys are taking up the space.

There are some tools that can provide the necessary help, such as redis-rdb-tools, which can directly analyze RDB files to generate reports. Unfortunately, it can't fulfill my requirements 100%, and I don't want to develop on top of it twice. In fact, the development of a dedicated tool is very simple, using SCAN and DEBUG commands, not many lines of code to achieve:


<?php $patterns = array(
    'foo:.+',
    'bar:.+',
    '.+',
); $redis = new Redis();
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY); $result = array_fill_keys($patterns, 0); while ($keys = $redis->scan($it, $match = '*', $count = 1000)) {
    foreach ($keys as $key) {
        foreach ($patterns as $pattern) {
            if (preg_match("/^{$pattern}$/", $key)) {
                if ($v = $redis->debug($key)) {
                    $result[$pattern] += $v['serializedlength'];
                }                 break;
            }
        }
    }
} var_dump($result); ?>

Of course, if you need to summarize possible key patterns in advance, the simple but less rigorous approach is MONITOR:


shell> /path/to/redis-cli monitor |
       awk -F '"' '$2 ~ "ADD|SET|STORE|PUSH" {print $4}'

Also, it is important to note that because DEBUG returns serializedlength as a serialized length, the final calculated value is less than the actual footprint, but it is still useful to consider the relative size.


Related articles: