业务场景中经常会有各种热key或大key的问题,如果未能及时处理,可能会导致服务性能下降、用户体验变差,甚至引发大面积故障。所以本文针对这两个问题进行讲解,提供发现/监控的方法以及处理的解决方案。
热key是服务端的常见问题,指一段时间内某个key的访问量远远超过其他的key,导致大量访问流量落在某一个redis实例中;或者是带宽使用率集中在特定的key(例如,对一个包含2000个field的hash key每秒发送大量的hgetall操作请求);又或者是cpu使用时间占比集中在特定的key(例如,对一个包含10000个field的key每秒发送大量的zrange操作请求)。
以被请求频率来定义是否是热key,没有固定经验值。某个key被高频访问导致系统稳定性变差,都可以定义为热key。
由于热key发生对系统稳定性有巨大危害,所以需要上线前设立故障预案、建立监控和报警机制,以便快速响应故障。
–-hotkeys
选项即可。大key是指当redis的字符串类型占用内存过大或非字符串类型元素数量过多。
生产环境中,综合衡量运维和环境的情况,给大key定义参考值如下:
不同系统性能条件不同,所以建议这个标准设置保守些,以系统稳定性为第一考量
maxmemory
参数定义的上限导致重要的Key被逐出,甚至引发内存溢出。慢查询为什么查不到。举例,如果请求进来且redis服务器正在进行过期键扫描,需要等待100毫秒。当客户端设置的超时时间小于100毫秒,那就会导致连接因为超时而关闭,就会造成异常,这些现象并不能从慢查询日志中查询到(因为慢查询只记录逻辑处理过程,不包括等待时间)。
使用工具定期扫描,并建立好监控和通知机制。
redis-cli --bigkeys
命令。可以用来找到某个实例5种数据类型(string、hash、list、set、zset)最大的key。redis-rdb-tools
工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析。memory usage
命令,通过随机抽样field的方式估算key的大小(样本越大,循环次数越多,计算结果越精确,性能消耗也越多)。编写python脚本,利用scan
和memory usage
命令,可以在集群低峰的时候扫描redis,排查大key。如果是redis4.0之前的版本,建议对于key使用(scan/sscan/hscan/zscan),将大key逐步删除(ltrim/zremrangebyscore/hdel/srem)。redis4.0之后,直接使用unlink替换del,会有后台线程将大key异步删除。
list_1,list_2,list_N
;其他数据结构同理。(可以考虑增加单独key存储大key被拆分的个数或元数据信息)