- hot key问题
热key是指某一个key访问量过大或者在多个分布式的redis节点中,某些请求频繁的key集中存在某个redis节点中使请求超过该节点的负载极限。
热key的危害
a. 流量集中,达到网卡上限,影响该机器的其他服务;
b. 请求过多,缓存分片服务被打垮。
c. 容易引发缓存击穿,数据库被干崩。
如何发现热key
a. 凭借业务经验,预估哪些是热key
b. 在客户端(业务代码中)进行收集
在操作redis之前,加入一行代码进行数据统计(或者调一个统计接口,由统计接口负责记录)。缺点就是对业务代码造成入侵和耦合。
如果所有的 Redis 请求都经过代理的话,可以考虑在 Proxy 层进行收集,该过程对客户端透明。
c. 用redis自带命令
monitor命令:该命令实时返回redis服务器接收到的命令(类似于 tail -f),然后客户端写代码统计出热key是啥。当然,也有现成的分析工具可以给你使用,比如redis-faina。
monitor命令在高并发的条件下,有内存增暴增的隐患(因为高并发下命令有很多),还会降低redis的性能。
hotkeys参数:执行 redis-cli --hot-keys 。但是该参数在执行的时候,如果key比较多,执行起来比较慢,而且只对LFU内存管理策略才有效(实现上是通过 scan + object freq 完成的,object内保存了key被访问的次数)。
如何解决热key问题
a. 备份热key,将某台机器的热key存到其他的redis节点中,进行负载均衡;
如果是在redis cluster分布式架构中,可以对热key加一个范围为(0~N)的随机数字后缀,使其hash之后分布到不同cluster节点中。客户端每次取该key时,由客户端拼接 0~N ,redis会根据key名从对应分片取出。
该方案的问题是如果要修改这个key就比较困难,涉及到多个节点的修改。
b. 采用二级缓存(本地缓存),即把热key加载到业务进程(一般业务进程也会部署运行在多机器上)中,请求就不会打到redis;
该方案的问题是要在本地缓存中定时删除不再使用的key,否则会造成内存泄漏。
- big key问题
big key 问题其本质是 big value问题。
针对不同的redis数据类型不同,big key的定义也不同:
value是String类型时,size超过10KB;
value是ZSET、Hash、List、Set等集合类型时,它的成员数量超过1w个;
具体由value包含的字节数决定。
big key 的危害
一句话:大key的读写耗时长,会阻塞redis主线程,阻塞其他key的读写,导致客户端等待耗时增加。
如何发现big key
a. 使用 redis-cli --big-keys,该命令会遍历所有key
b. 使用redis-rdb-tools离线分析工具来扫描RDB持久化文件,虽然实时性略差,但是完全离线对性能无影响。
c.基于某些公有云或者公司内部架构的redis一般都会有可视化的页面和分析工具,来帮助我们定位大key
如何处理big key
对于不常用的 big key 可以从redis删除并存到db中,删除时用unlink命令可以实现异步删除(不要用delete)。
对于常用的big key可以对其进行拆分:
当value是string,可以将一个大key分为不同的部分(将一个对象按多个成员属性存储,当然别存成一个hash,因为这个hash还是一个大key),使用multiget等操作实现事务读取。
当value是list/set等集合类型时,可以将一个list分成多个小list,不同的元素通过hash计算后分到不同的list。