RedisJSON 指令精讲JSON.STRLEN 高效统计字符串长度
1 · 场景与价值
在日志累加、指标采集、消息追踪等场景中,我们常需快速判断某个字符串字段“到底有多长”,以便:
- 阻止过大日志:若长度超限则截断或归档;
- 动态分桶:按长度选择不同存储策略;
- 性能监控:突然飙长可能暗示异常循环或恶意输入。
有了 JSON.STRLEN
,无需把整段内容取回客户端,也无需额外存副本,即可 O(1) 地获取字段长度。
2 · 指令概览
JSON.STRLEN key [path]
- 可用版本:RedisJSON ≥ 1.0
- ACL 标签:
@json @read @slow
- 默认路径:
$
(根)
3 · 语法参数
JSON.STRLEN []
key
path
$
返回值
- 若匹配为字符串:返回其长度(整型)。
- 若路径不存在 / 类型非字符串:返回
nil
。 - 多路径:递归数组,顺序对应各匹配点。
4 · 基本示例
redis> JSON.SET doc $ \'{\"a\":\"foo\",\"nested\":{\"a\":\"hello\"},\"nested2\":{\"a\":31}}\'OK# 多路径统计redis> JSON.STRLEN doc $..a1) (integer) 3 # $.a -> \"foo\"2) (integer) 5 # $.nested.a -> \"hello\"3) (nil) # $.nested2.a 不是字符串
5 · 常见用法场景
5.1 日志超长保护
> len=$(redis-cli JSON.STRLEN log:123 $.trace)> if [ \"$len\" -gt 2048 ]; then> redis-cli JSON.SET log:123 $.trace \'\"\"\'> fi
5.2 统计动态字段占用
# 查看所有用户简介 bio 的平均长度redis-cli --raw KEYS \"user:*\" | while read k; do redis-cli JSON.STRLEN $k $.biodone | awk \'{s+=$1;c++} END{print s/c}\'
6 · 踩坑与注意
nil
,误以为不存在JSON.TYPE
或保证字段类型一致$..field
nil
EXISTS
或 JSON.TYPE
判断STRLEN
只算字节数,不是元素数,数组用 JSON.ARRLEN
7 · Go-Redis 完整示例
package mainimport (\"context\"\"fmt\"\"log\"\"github.com/redis/go-redis/v9\")func main() {ctx := context.Background()rdb := redis.NewClient(&redis.Options{Addr: \"localhost:6379\"})defer rdb.Close()// 初始化测试文档_, err := rdb.Do(ctx, \"JSON.SET\", \"msg:1\", \"$\",`{\"body\":\"hello world\",\"meta\":{\"note\":\"short\"}}`).Result()if err != nil { log.Fatal(err) }// 1️⃣ 单路径长度len1, _ := rdb.Do(ctx, \"JSON.STRLEN\", \"msg:1\", \"$.body\").Int64()fmt.Println(\"body len =\", len1) // 11// 2️⃣ 多路径长度res, _ := rdb.Do(ctx, \"JSON.STRLEN\", \"msg:1\", \"$..note\").Slice()fmt.Println(\"meta.note len =\", res[0]) // 5// 3️⃣ 类型不符示例_, _ = rdb.Do(ctx, \"JSON.SET\", \"msg:1\", \"$.count\", 100)res2, _ := rdb.Do(ctx, \"JSON.STRLEN\", \"msg:1\", \"$.count\").Slice()fmt.Printf(\"count -> %#v\\n\", res2[0]) // }
8 · 性能建议
-
批量调用使用 Pipeline
pipe := rdb.Pipeline()keys := []string{\"user:1\", \"user:2\", \"user:3\"}for _, k := range keys { pipe.Do(ctx, \"JSON.STRLEN\", k, \"$.bio\")}_, _ = pipe.Exec(ctx)
-
监控慢查询
复杂 JSON + 多路径 ($..field
) 会触发 SLOWLOG,需关注。 -
字符串膨胀预警
可用MEMORY USAGE key
+JSON.STRLEN
建立长度阈值报警。
9 · 与其它指令的协同
JSON.STRAPPEND
→ JSON.STRLEN
JSON.STRLEN
+ JSON.SET
JSON.TYPE
+ JSON.STRLEN
10 · 总结
JSON.STRLEN
提供 O(1) 字段级长度统计,是日志与配额场景的利器。- 返回值为整型或
nil
,多路径时请按序处理。 - 精准路径 ≫ 通配路径,能显著降低 O(N) 扫描成本。
- 在 Go-Redis 中用
Do()
一行即可调用,并能与 Pipeline/事务无缝整合。
至此,字符串家族三兄弟 STRLEN / STRAPPEND / SET 已全部集齐。灵活运用它们,你的 RedisJSON 文档读写将更加高效、细粒度且安全。祝编码愉快,欢迎留言交流实践体会!