Redis 大 key 问题
大 key 标准 在一般的业务场景下(并发和容量要求都不大): 单个string的value>1MB 容器ds元素数量超过10000 在高并发且低延迟的场景中:(互联网上看到比较多的版本) 单个string的value>10KB 容器ds元素数量超过5000或整体value>10MB 阿里云的云版本Redis: Key本身的数据量过大:一个String类型的Key,它的值为5MB Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10000个 Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1000个但这些成员的Value(值)总大小为100MB 但其实Redis大key问题的定义及评判准则并非一成不变,没有固定的判别标准,还是要根据Redis在实际业务中的使用来综合评估。(注意边界问题) 大 key 影响 读取成本高 时延(执行命令时间更长) 带宽(大 key 消耗更多的带宽,从而影响相关服务) 大key的写操作容易阻塞,从而导致无法正常响应 慢查询 主从同步异常 占更多的存储空间,从而导致逐出,甚至是 OOM(Out Of Memory) 集群架构下,某个数据分片的内存使用率远超其他数据分片,即数据分片的内存资源不均衡 [!DANGER] 根本原因 Redis 是单线程! 大 key 产生原因 业务设计不合理。这是最常见的原因,不经过合理拆分,就直接把大json塞在一个key中;甚至塞二进制文件数据。 没有处理好value的动态增长问题。如果一直添加value数据,没有定期的删除机制、合理的过期机制或者卡量,大key只是早晚的问题。(例如:微博明星的粉丝列表、热门评论、直播弹幕等) 程序bug。某些异常情况导致某些key的生命周期超出预期,或者value数量异常增长。比如LIST的业务消费侧发生代码故障,造成对应Key的成员只增不减。 找到大 key bigkeys 参数 参考官方文档:https://redis.io/docs/latest/develop/connect/cli/#scanning-for-big-keys 使用redis-cli命令客户端,连接Redis服务的时候,加上 --bigkeys 参数,可以以遍历的方式分析Redis实例中的所有Key,并返回Key的整体统计信息与每个数据类型中Top1的大Key。(原理是基于SCAN) $ redis-cli --bigkeys # Scanning the entire keyspace to find biggest keys as well as # average sizes per key type. You can use -i 0.01 to sleep 0.01 sec # per SCAN command (not usually needed). [00.00%] Biggest string found so far 'key-419' with 3 bytes [05.14%] Biggest list found so far 'mylist' with 100004 items [35.77%] Biggest string found so far 'counter:__rand_int__' with 6 bytes [73.91%] Biggest hash found so far 'myobject' with 3 fields -------- summary ------- Sampled 506 keys in the keyspace! Total key length in bytes is 3452 (avg len 6.82) Biggest string found 'counter:__rand_int__' has 6 bytes Biggest list found 'mylist' has 100004 items Biggest hash found 'myobject' has 3 fields 504 strings with 1403 bytes (99.60% of keys, avg size 2.78) 1 lists with 100004 items (00.20% of keys, avg size 100004.00) 0 sets with 0 members (00.00% of keys, avg size 0.00) 1 hashs with 3 fields (00.20% of keys, avg size 3.00) 0 zsets with 0 members (00.00% of keys, avg size 0.00) [!TIP] 总结 ...