【问题标题】:What is the easiest way to find the biggest objects in Redis?在 Redis 中找到最大对象的最简单方法是什么?
【发布时间】:2020-05-07 21:31:59
【问题描述】:

我在生产中有一个 20GB+ 的 rdb 转储。 我怀疑有一组特定的键使其膨胀。 我希望有一种方法可以始终从静态转储分析中找出前 100 个最大的对象,或者将其发送给服务器本身,顺便说一下,服务器本身有超过 7M 的对象。

像 rdbtools 这样的转储分析工具在这个(我认为)非常常见的用例中没有帮助!

我正在考虑编写一个脚本并使用“redis-cli 调试对象”迭代整个键集,但我觉得肯定缺少一些工具。

【问题讨论】:

    标签: redis


    【解决方案1】:

    在 redis-cli 中添加了一个选项:redis-cli --bigkeys

    基于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)
    

    【讨论】:

    • 终于在 2 年后真正解决了这个问题。谢谢。
    • 这是一个从 2.8 开始的“新”功能(并向后移植到 2.6)......所以它已经存在了 18 个月左右......只是说'(嘿,西蒙妮!;))
    • 嗨 Itamar :D 我想当我把所有东西都移到 ARDB 时,我就不再寻找解决方案了。但很高兴知道!
    • 有这样的东西可以对整个 Redis 集群的键进行操作吗?我认为在集群中利用此功能的唯一方法是编写脚本以在每个主节点上运行,然后聚合。如果有更好的方法,那就太棒了。
    【解决方案2】:

    redis-rdb-tools 确实有一个内存报告,可以满足您的需求。它会生成一个 CSV 文件,其中包含每个键使用的内存。然后您可以对其进行排序并找到前 x 个键。

    还有一个实验性的内存分析器可以开始做你需要的事情。它尚未完成,因此没有记录。但你可以试试 - https://github.com/sripathikrishnan/redis-rdb-tools/tree/master/rdbtools/cli。当然,我也鼓励你做出贡献!

    免责声明:我是此工具的作者。

    【讨论】:

    • 支持离线解决问题的方法。 CSV 文件非常大,需要解析/排序。
    • @sscarduzio - 我创建了问题github.com/sripathikrishnan/redis-rdb-tools/issues/19 来跟踪这个问题。如果有机会,我将更新解析器以维护和显示内存使用情况的前 N ​​个键。
    • 拥有该功能将非常有用。谢谢!
    • 我最近添加了一个参数来按密钥大小进行过滤,并且只返回 N 个最大的密钥,这两个参数都在我的项目分支中 - github.com/joshtronic/redis-rdb-tools - 干杯!
    【解决方案3】:

    我对 bash 脚本很陌生。我想出了这个:

    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
    

    这个脚本

    • 列出所有带有redis-cli keys "*"的键
    • 使用redis-cli DEBUG OBJECT 获取大小
    • 根据前面加大小的名称对脚本进行排序

    这可能非常慢,因为 bash 正在循环遍历每个 redis 键。您有 7m 个密钥,您可能需要将密钥的输出缓存到文件中。

    【讨论】:

    • serializedlength 实际上是一个很差的内存指标。对于使用 Redis 特殊编码的小对象,它是准确的。但对于较大的物体,它完全不符合标准。较大的对象由于指针而具有开销,并且它们可能在序列化版本中被压缩——这两者都没有计入序列化长度。
    • 感谢@peterpan,但是考虑到键的数量以及需要以如此庞大的方式直接与生产服务器交互,bash 循环 |sort 从来都不是一个选项。
    【解决方案4】:

    如果您有遵循这种模式“A:B”或“A:B:*”的键,我编写了一个工具,可以分析现有内容以及监控诸如命中率、获取/集数等内容、网络流量、生命周期等。输出类似于下图。

    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 |
    

    【讨论】:

      【解决方案5】:

      试试redis-memory-analyzer - 一个控制台工具,用于实时扫描 Redis 键空间并按键模式聚合内存使用统计信息。您可以在生产服务器上使用此工具而无需维护。它向您显示有关 Redis 服务中每个关键模式的详细统计信息。

      您还可以按所有或选定的 Redis 类型(例如“string”、“hash”、“list”、“set”、“zset”)扫描 Redis db。还支持匹配模式。

      RMA 还尝试通过模式识别键名,例如,如果您有像“user:100”和“user:101”这样的键,应用程序会在输出中挑选出常见的模式“user:*”,这样您就可以分析大部分内存您实例中的不良数据。

      【讨论】:

      • 它似乎只适用于python >= 3.4。对python 2.7有什么建议吗?
      • @misterion:我通过 python3.6 -m pip install rma 安装了 RMA,它安装成功。当我输入 python3.6 -m rma 它说 /usr/local/bin/python3.6: No module named rma.__main__; 'rma' 是一个包,不能直接执行
      猜你喜欢
      • 2019-04-26
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 2010-12-29
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多