IT技术博客大学习 共学习 共进步

如何统计Redis中各种数据的大小

火丁笔记 2015-03-26 13:32:09 浏览 2,701 次

   如果 MySQL 数据库比较大的话,我们很容易就能查出是哪些表占用的空间;不过如果 Redis 内存比较大的话,我们就不太容易查出是哪些(种)键占用的空间了。

   有一些工具能够提供必要的帮助,比如 redis-rdb-tools 可以直接分析 RDB 文件来生成报告,可惜它不能百分百实现我的需求,而我也不想在它的基础上二次开发。实际上开发一个专用工具非常简单,利用 SCANDEBUG 等命令,没多少行代码就能实现:

<?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);

?>

   当然,前提是你需要提前总结出可能的键模式,简单但不严谨的方法是 MONITOR

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

   此外,需要注意的是:因为 DEBUG 返回的 serializedlength 是序列化后的长度,所以最终计算的值小于实际内存占用,但考虑到相对大小依然是有参考意义的。

建议继续学习

  1. redis源代码分析 - persistence (阅读 32,101)
  2. Redis消息队列的若干实现方式 (阅读 11,922)
  3. 基于Redis构建系统的经验和教训 (阅读 10,380)
  4. 浅谈redis数据库的键值设计 (阅读 9,220)
  5. redis运维的一些知识点 (阅读 8,520)
  6. redis在大数据量下的压测表现 (阅读 8,200)
  7. Redis和Memcached的区别 (阅读 7,940)
  8. redis 运维实际经验纪录之一 (阅读 7,582)
  9. Redis作者谈Redis应用场景 (阅读 7,540)
  10. 记Redis那坑人的HGETALL (阅读 7,320)