2023-06-29:redis中什么是热点Key?该如何解决?
阅读原文时间:2023年09月07日阅读:5

2023-06-29:redis中什么是热点Key?该如何解决?

答案2023-06-29:

在Redis中,经常被访问的key被称为热点key。

产生原因和危害

原因

热点key问题产生的原因可以归纳为以下两种情况:

用户对于某些数据的访问频率远大于数据的生产频率,这类数据包括热门商品、热点新闻、热点评论以及明星直播等。

在日常工作生活中,突发事件(如双十一期间商品降价促销)可能导致某些热门商品被大量点击浏览或购买,产生了巨大的需求量。类似地,热点新闻、热点评论和明星直播等引起大量刊发和浏览的情况也是典型的读多写少场景,它们会产生热点问题。

请求集中在分片集群中,超过单个服务器的性能极限。在服务端进行数据访问时,通常会对数据进行分片切分,其中某个服务器上的热点Key访问量超过了其承载能力的极限,从而导致热点Key问题的出现。

危害

1、流量集中,超过物理网卡的处理能力上限。

2、请求过多,导致缓存分片服务崩溃。

3、数据库击穿,引发业务雪崩。

发现热点key

预估发现

针对业务,可以提前预估出访问频繁的热点Key,例如在秒杀商品业务中,秒杀商品就是热点Key的典型案例。

然而,并非所有业务都容易预估出热点Key,有时可能会出现对热点Key的遗漏或预估错误的情况。

客户端发现

客户端实际上是离"热点Key"最近的位置,因为Redis命令是由客户端发送的。以Jedis为例,在核心命令入口处使用Google Guava中的AtomicLongMap可以方便地记录热点Key的访问情况,示例如下:

然而,使用客户端进行热点Key的统计也存在一些问题:

(1) 无法预知热点Key的数量,可能存在内存泄露的风险。

(2) 在不同的客户端代码中需要维护此逻辑,可能增加维护成本。

(3) 在规模化汇总方面的实现相对复杂。

Redis发现

monitor命令

使用Redis的monitor命令,可以监控到Redis执行的所有命令。通过解析monitor的结果,我们可以统计一段时间内的热点Key排行榜、命令排行榜以及客户端分布等数据。这种方法能够提供更详细的信息,帮助我们深入了解Redis的使用情况。需要注意的是,在生产环境中使用monitor命令可能对性能产生一定的影响,因此应该谨慎使用,并注意网络开销和输出缓冲区的消费速度。

Redis-Faina是Facebook开源的一款使用Python语言实现的工具。它利用上述原理可以获取最近10万条命令的热点Key、热点命令以及命令执行的耗时分布等数据。为了减少网络开销并提高输出缓冲区的消费速度,Redis-Faina会尽可能地在本机执行monitor命令。使用Redis-Faina可以更详细地了解Redis的使用情况。需要注意,在生产环境中使用该工具时应考虑性能影响和安全性。

此种方法存在两个问题:

1、在高并发条件下,使用monitor命令会导致内存暴增,同时可能影响Redis的性能。因此,这种方法适合在短时间内使用,而不适合长时间或高并发的监控。

2、monitor命令只能统计单个Redis节点的热点key,对于Redis集群,需要进行汇总统计才能获取全集群的热点key信息。

可以参考的框架:Facebook开源的redis-faina正是利用上述原理使用Python语言实现的

hotkeys

Redis在版本4.0.3中为redis-cli提供了--hotkeys选项,用于方便地找到热点key。通过使用该选项,我们可以快速获取到Redis中的热点key信息。这个功能的引入为我们在分析和优化Redis性能时提供了更方便和直接的工具。需要注意的是,确保Redis版本符合要求,并使用适当的命令行选项来获得所需的热点key信息。

如果发生错误,确保先将内存逐出策略设置为allkeys-lfu或者volatile-lfu,否则可能会返回错误。

然而,如果键值非常多,执行此操作可能会变得相对较慢,这与热点的概念有些相悖。此外,热度的定义可能不够准确。

抓取TCP包发现热点key

Redis客户端使用TCP协议与服务端进行交互,通信协议采用RESP。可以通过对机器上所有Redis端口的TCP数据包进行抓取来完成热点key的统计。这种方法对Redis客户端和服务端没有侵入,是一种较完美的方案。然而,存在以下三个问题:

1.需要进行一定的开发工作。

2.对于高流量的机器抓包,可能会对机器网络产生干扰,并可能丢包。

3.维护成本较高。

为了解决这些问题,有一些开源方案如ELK(ElasticSearch, Logstash, Kibana)体系下的packetbeat插件可以实现Redis、MySQL等服务的数据包抓取、分析和报表展示。

处理热点key

发现热点key后,可以采取以下方法进行处理:

  1. 使用二级缓存:使用Guava Cache或HCache将热点key加载到JVM中作为本地缓存。访问这些key时,直接从本地缓存获取数据,避免直接访问Redis层,有效保护缓存服务器。

  2. key分散:将热点key分散为多个子key,并分别存储在缓存集群的不同机器上。这些子key的值与热点key相同。当通过热点key查询数据时,通过某种哈希算法随机选择一个子key,然后再访问缓存机器,将热点key分散到多个子key上。

请注意,以上只是几种处理热点key的方法,根据实际需求和系统情况,可能还会有其他适合的解决方案。