
如何处理Redis集群中的Big key和Hot keys
作者 | 川石信息
来源 | 今日头条
Big key
即数据量大的 key ,由于其数据大小远大于其他key,导致经过分片之后,某个具体存储这个 big key 的实例内存使用量远大于其他实例,造成,内存不足,拖累整个集群的使用。big key 在不同业务上,通常体现为不同的数据,比如:
- 论坛中的大型持久盖楼活动;
- 聊天室系统中热门聊天室的消息列表;
Hot key
即热点 key,指的是在一段时间内,该 key 的访问量远远高于其他的 redis key, 导致大部分的访问流量在经过 proxy 分片之后,都集中访问到某一个 redis 实例上。hot key 通常在不同业务中,存储着不同的热点信息。比如:
- 新闻应用中的热点新闻内容;
- 活动系统中某个用户疯狂参与的活动的活动配置;
(1)查看Big key
(2)bigkey带来的问题:
1.内存空间不均匀
在集群模式中,由于bigkey的存在,会造成主机节点的内存不均匀,这样会不利于集群对内存的统一管理,存在丢失数据的隐患。
2.超时阻塞
由于redis单线程的特性,操作bigkey通常比较耗时,也就意味着阻塞redis可能性越大,这样会造成客户端阻塞或者引起故障切换。慢查询通常就会有它们的身影。
3.网络拥塞
bigkey也就意味着每次获取要产生的网络流量较大。假设一个bigkey为1MB,客户端每秒访问量为1000,那么每秒产生1000MB的流量,对于普通的千兆网卡(按照字节算是128MB/s)的服务器来说简直是灭顶之灾。
4.阻塞删除
有个bigkey,对它设置了过期时间,当它过期后会被删除,如果使用Redis 4.0之前的版本,过期key是异步删除,就会存在阻塞redis的可能性,而且这个过期删除不会从慢查询发现(因为这个删除不是客户端产生的,是内部循环事件)。
bigkey的产生主要是由于程序的设计不当所造成的,如以下几种常见的业务场景:
社交类:粉丝列表,如果某些明星或者大v不精心设计下,必是bigkey。
统计类:例如按天存储某项功能或者网站的用户集合,除非没几个人用,否则必是bigkey。
缓存类:将数据从数据库load出来序列化放到redis里,这个方式经常常用,但有两个地方需要注意:第一,是不是有必要把所有字段都缓存;第二,有没有相关关联的数据。
(3)优化 bigkey
优化big key的原则就是string减少字符串长度,list、hash、set、zset等减少成员数;string长度大于10K,list长度大于10240认为是big bigkeys。
1.拆分
如果对象是整存争取,将对象拆分后才能多个小key-value,get不同的key或者批量获取stringRedisTemplate.opsForValue() .multiGet(keyList)
如果对象是部分更新获取数据,可以分拆成几个key-value,也可以存储在hash中,部分更新部分存取!
2.本地缓存
减少访问redis次数,降低危害减少访问redis次数,降低危害!当然本地开销也会变大!
Redis 4.0.3中新增查看热点数据命令行,使用热点数据必须将内存策略修改为LFU算法。
查看内存策略
查看 key 使用频率
Hot key 错误
如果在查看key使用频率或查看hot key时出现以下错误,那就必须先修改LFU算法
Least Frequently Used:最不经常使用。
Redis有两种LFU算法:
- volatile-lfu:设置了过期时间的key中,进行LFU淘汰。
- allkeys-lfu:所有key参与LFU淘汰。
更改内存策略
查看热点数据
统计时间隔0.1秒,防止阻塞其他线程。
