Redis大key和热key

在字节面试的过程中有一个面试官问了一个redis中大key和热key的问题,大key和热key是什么,会引发的问题,如何发现大key和热key,怎么解决大key和热key的问题。

定义

大Key

大Key通常都会以数据大小与成员数量来判定 :

通常以Key的值大小和Key中成员的数量来综合判定,例如:

  • Key本身的值数据量过大:一个String类型的Key,它的值为5 MB。
  • Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10,000个。
  • Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的Value(值)总大小为100 MB。

热Key

热Key则以其接收到的请求频率、数量来判定:

通常以其接收到的Key被请求频率来判定,例如:

  • QPS集中在特定的Key:Redis实例的总QPS(每秒查询率)为10,000,而其中一个Key的每秒访问量达到了7,000。
  • 带宽使用率集中在特定的Key:对一个拥有上千个成员且总大小为1 MB的HASH Key每秒发送大量的HGETALL操作请求。
  • CPU使用时间占比集中在特定的Key:对一个拥有数万个成员的Key(ZSET类型)每秒发送大量的ZRANGE操作请求。

引发的问题

大Key

  • 阻塞请求:客户端执行命令的时长变慢。
  • 内存不均:Redis内存达到maxmemory参数定义的上限引发操作阻塞或重要的Key被逐出,甚至引发内存溢出(Out Of Memory)。某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡。
  • 阻塞网络:对大Key执行读请求,会使Redis实例的带宽使用率被占满,导致自身服务变慢,同时易波及相关的服务。对大Key执行删除操作,易造成主库较长时间的阻塞,进而可能引发同步中断或主从切换。

热Key

  • 流量集中,达到服务器处理上限(CPU、网络 IO 等);
  • 会影响在同一个 Redis 实例上其他 Key 的读写请求操作;
  • Key 请求落到同一个 Redis 实例上,无法通过扩容解决;
  • 大量 Redis 请求失败,查询操作可能打到数据库,拖垮数据库,导致整个服务不可用。

产生的原因

大key

  • 在不适用的场景下使用Redis,易造成Key的value过大,如使用String类型的Key存放大体积二进制文件型数据;
  • 业务上线前规划设计不足,没有对Key中的成员进行合理的拆分,造成个别Key中的成员数量过多;
  • 未定期清理无效数据,造成如HASH类型Key中的成员持续不断地增加;
  • 使用LIST类型Key的业务消费侧发生代码故障,造成对应Key的成员只增不减。

热key

预期外的访问量陡增,如突然出现的爆款商品、访问量暴涨的热点新闻、主播搞活动带来的大量刷屏点赞等

如何发现

大Key

  • 实时Top Key统计
  • 离线全量Key分析

热Key

  • 客户端收集上报
  • 代理层收集上报
  • Redis 数据定时扫描hotkeys 查找特性,可以直接利用 redis-cli --hotkeys 获取当前 keyspace 的热点 key,实现上是通过 scan + object freq 完成的
  • Redis 节点抓包解析

怎么解决

大Key

  • 对大Key进行拆分
  • 对大Key进行清理
  • 监控Redis的内存
  • 对过期数据进行定期清理

热Key

  • 增加 Redis 实例复本数量: 分担读流量

  • 热 Key 备份: 比如key,备份为key1,key2……keyN,同样的数据N个备份,N个备份分布到不同分片,访问时可随机访问N个备份中的一个,进一步分担读流量

  • 二级缓存(本地缓存): 使用本地缓存,发现热key后,将热key对应数据加载到应用服务器本地缓存中,访问热key数据时,直接从本地缓存中获取,而不会请求到redis服务器。

MySQL INSERT INTO table VALUES.. vs INSERT INTO table SET
标签:

发表我的评论

电子邮件地址不会被公开。 必填项已用*标注

ajax-loader