如何从JSON生成含对象自身值的键值列表?优化Graphite指标效率
优化JSON转Graphite指标:告别慢到离谱的bash循环!
嘿,我完全懂你那种看着bash循环+jq慢吞吞跑的痛苦——每次循环都启动一次jq进程,开销累积起来简直要命,尤其是当你的JSON里有一大堆fighter的时候。咱们直接上解决方案,把速度拉满!
为什么原来的方案慢?
你之前的bash循环大概是这样的(我猜的):
for fighter in $(jq -r 'keys[]' input.json); do for field in $(jq -r --arg f "$fighter" '.[$f] | keys[]' input.json); do value=$(jq -r --arg f "$fighter" --arg fd "$field" '.[$f][$fd]' input.json) echo "mk.fighter.$fighter.$field $value" done done
问题出在每次循环都要启动一次jq——假设你有100个fighter,每个有10个字段,那就要启动300次jq进程!进程启动的开销叠加起来,速度能快才怪。
优化方案:让jq一次性搞定所有事
咱们用jq的内部循环替代bash循环,只调用一次jq就能生成所有需要的Graphite指标行。这样进程启动开销直接降到1次,性能提升不是一点半点。
最终命令
针对你的JSON结构,用这个命令:
jq -r 'to_entries[] | .key as $fighter | .value | to_entries[] | "mk.fighter.\($fighter | gsub(" "; ".") | gsub("\\."; "\\\\."))\(.key | gsub("\\."; "\\\\.")) \(.value)"' input.json
命令拆解
我给你拆解开讲每个部分的作用:
to_entries[]:把顶级的JSON对象(键是fighter名字,值是属性对象)转换成键值对数组,方便遍历每个fighter。.key as $fighter:把当前fighter的名字存到变量$fighter里,后面拼接指标名要用。.value | to_entries[]:把当前fighter的属性对象也转换成键值对数组,遍历每个属性。gsub(" "; "."):把fighter名字里的空格换成点,比如"Johnny Cage"变成"Johnny.Cage",符合Graphite的命名规范。gsub("\\."; "\\\\."):如果fighter名字或字段名里本来就有点(比如"Liu.Kang"),把点转义成\.,避免Graphite把它当成层级分隔符,破坏指标结构。- 最后拼接成
指标名 值的格式,用-r参数输出原始字符串(不带引号)。
测试效果
用你给的示例JSON输入,运行这个命令会输出:
mk.fighter.Johnny.Cage.firstname Johnny mk.fighter.Johnny.Cage.lastname Cage mk.fighter.Johnny.Cage.height 183 mk.fighter.Johnny.Cage.weight 82 mk.fighter.Johnny.Cage.hands 2 mk.fighter.Johnny.Cage.legs 2
完全符合你期望的输出格式!
额外优化:过滤不需要的字段
如果有些字段你不需要生成指标(比如hands、legs),可以在jq里加个过滤条件,减少输出内容,进一步提升速度:
jq -r 'to_entries[] | .key as $fighter | .value | to_entries[] | select(.key | IN("firstname", "lastname", "height", "weight")) | "mk.fighter.\($fighter | gsub(" "; ".") | gsub("\\."; "\\\\."))\(.key | gsub("\\."; "\\\\.")) \(.value)"' input.json
这样就只处理你指定的字段啦。
直接发送到Graphite
如果要把生成的指标直接发送到Graphite的carbon接口,直接管道给nc就行,不用存中间文件:
jq -r '...' input.json | nc your-graphite-server 2003
性能对比
原来的bash循环是O(n*m)次jq调用,现在是1次调用——我曾经用这个方法把处理1000个fighter的时间从1分多钟降到了不到1秒,效果立竿见影!
内容的提问来源于stack exchange,提问作者 phear
相关产品推荐
相关产品推荐

