- 热key占用大量的cpu资源,使其效率降低,影响其他业务
- 热key所在的节点访问量大,容易造成物理网卡瓶颈
- 超出redis承受能力后,容易造成击穿,这时大量访问去到数据库,对数据库造成瓶颈
如何解决:
- 对热key根据一定的规则,增加后缀,让它变成好几个key,分散到不同的节点中,减少一个节点的压力,他也有一定的问题,比如数据一致性问题。更新一个key变成更新多个,业务代码也要修改,增加工作量
- 对热点的key单独做集群,他们会有独立热点key redis集群,和全量redis隔离开,当然这样产生费用也时比较大的
- 使用读写分离,这样可以避免对写操作的影响,但是读写分离会有延迟的情况
- 本地缓存,可以客户端对热key进行收集做缓存,比如浏览器的localstorage,安卓ios自己的数据库,然后设置一个比较短的过期时间,比如1分钟,用来解决信息的更新问题【默认】
- 系统服务来做,代码自己来实现,比如java的ehcache,也可以在系统服务的服务器上安装redis和memcache,这样访问热key的时候就不用和redis集群交互了
bigkey:
对于不同的数据类型,定义不同:
String类型:根据数据量,value值超过10KB
List类型:根据列表大小,列表大小超过20000
Set类型:根据成员多少,成员超过10000
Hash类型:成员的数据量过大,它的成员数量虽然只有1000个但这些成员的Value总大小为100 MB
redis客户端可以用bigkeys命令来查找
redis-cli --bigkeys
- 查询BigKey时用时较长,有可能会阻塞其它请求。
- Redis内存达到maxmemory参数定义的上限引发操作阻塞或重要的Key被逐出,甚至引发内存溢出(Out Of Memory)。
- 集群架构下,某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡。
- 查询BigKey时,可能造成网络带宽占满,影响其它服务。
- 对大Key执行删除操作,易造成主库较长时间的阻塞,进而可能引发同步中断或主从切换。
大key的删除解决办法:
低访问时间段删除
list set zset hash可以分批次删除
使用unlink代替del命令,异步删除,不会阻塞主线程