Redis 集群热点 Key 问题主要通过配置客户端本地缓存、利用分片算法对 Key 进行打散处理(如添加随机后缀)、以及启用 Redis 4.0+ 的热点 Key 发现功能来缓解。具体而言,可以在客户端引入本地缓存减少对集群的直接访问压力;通过给热点 Key 添加前缀或后缀,将一个 Key 的访问量分散到多个 Redis 实例上,实现负载均衡;此外,利用 Redis 集群监控和 redis-cli 的--hotkeys 参数配置,可以及时发现并定位热点 Key,从而采取针对性的优化措施,避免单点性能瓶颈导致的集群故障。
如何处理 redis 集群的 hot key 和 big key
redis 集群部署方式大部分采用类 Twemproxy 的方式进行部署。即通过 Twemproxy 对 redis key 进行分片计算,将 redis key 进行分片计算,分配到多个 redis 实例中的其中一个。tewmproxy 架构图如下:常见的 tewmproxy 架构 由于 Twemproxy 背后的多个 redis 实例在内存配置和 cpu 配置上都是一致的,所以一旦出现访问量倾斜或者数据量倾斜,则可能会导致某个 redis 实例达到性能瓶颈,从而使整个集群达到性能瓶颈。hot key 出现造成集群访问量倾斜 Hot key,即热点 key,指的是在一段时间内,该 key 的访问量远远高于其他的 redis key,导致大部分的访问流量在经过 proxy 分片之后,都集中访问到某一个 redis 实例上。hot key 通常在不同业务中,存储着不同的热点信息。比如 1. 新闻应用中的热点新闻内容; 2. 活动系统中某个用户疯狂参与的活动的活动配置; 3. 商城秒杀系统中,最吸引用户眼球,性价比最高的商品信息; …… 解决方案 1. 使用本地缓存 在 client 端使用本地缓存,从而降低了 redis 集群对 hot key 的访问量,但是同时带来两个问题:1、如果对可能成为 hot key 的 key 都进行本地缓存,那么本地缓存是否会过大,从而影响应用程序本身所需的缓存开销。2、如何保证本地缓存和 redis 集群数据的有效期的一致性。针对这两个问题,先不展开讲,先将第二个解决方案。2. 利用分片算法的特性,对 key 进行打散处理 我们知道 hot key 之所以是 hot key,是因为它只有一个 key,落地到一个实例上。所以我们可以给 hot key 加上前缀或者后缀,把一个 hotkey 的数量变成 redis 实例个数 N 的倍数 M,从而由访问一个 redis key 变成访问 N * M 个 redis key。N*M 个 redis key 经过分片分布到不同的实例上,将访问量均摊到所有实例。代码如下:代码语言:javascript AI 代码解释 //redis 实例数 const M = 16 //redis 实例数倍数 (按需设计,2^n 倍,n 一般为 1 到 4 的整数) const N = 2 func main() { //获取 redis 实例 c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() hotKey := "hotKey:abc" //随机数 randNum := GenerateRangeNum(1, N*M) //得到对 hot key 进行打散的 key tmpHotKey := hotKey + "_" + strconv.(发布时间是 2026 年 4 月 13 日)
Redis 热点 key 及大 key 解决方案
1 热点 key 问题 如果 Key 特别热,可能 Redis 也无法承受,毕竟所有的访问都集中打到了一台缓存服务器。如果我们使用 Redis 来做缓存,那可以把一个热点 Key 的缓存查询压力,分散到多个 Redis 节点上吗?加随机后缀。场景 在一个非常热点的数据,数据更新不是很频繁,但是查询非常频繁,要保证基本保证 100% 的缓存命中率,该怎么处理?方案 核心思想:空间换时间,即同一热点 key 保留 2 份:不带后缀 不带的后缀的有 TTL 带后缀 带后缀的没有 TTL 先查询不带后缀的,查询不到,则:后端查询 DB 更新缓存 查询带后缀返回给调用方 这样即可尽可能避免缓存击穿。2 大 Key 如果一个 Key 的 Value 特别大,那么可能会对 Redis 产生巨大的性能影响,因为 Redis 是单线程模型,对大 Key 进行查询或删除等操作,可能会引起 Redis 阻塞甚至是高可用切换。应该如何查询 Redis 中的大 Key,以及如何在设计上实现大 Key 的拆分呢?2.1 单个 K 存储的 V 很大 key 分类如下:该 key 需要每次都整存整取 尝试将对象分拆成几个 K.V,使用 multiGet 获取值。拆分旨在降低单次操作的压力,将操作压力平摊到多个 Redis 实例,降低对单个 redis 的 I/O 影响。该对象每次只需要存取部分数据 类似上一种方案,拆分成几个 K.V 也可将这个大对象存储在一个 hash,每个 field 代表一个具体属性 hget、hmget 获取部分 value hset,hmset 来更新部分属性 2.2 一个集群存储了上亿 key 如果 key 个数过多,会带来更多内存空间占用:key 本身的占用 每个 key 都会有一个 Category 前缀 集群模式中,服务端需要建立一些 slot2key 的映射关系 这其中的指针占用在 key 多的情况下也是浪费巨大空间 这两方面在 key 个数上亿时消耗内存十分明显 (Redis 3.2 及以下版本均存在这个问题,4.0 有优化)。所以减少 K 个数可以减少内存消耗,可以参考的方案是转 Hash 结构存储,即原先是直接使用 Redis String 的结构存储,现在将多个 key 存储在一个 Hash 结构:2.2.1 key 本身就有很强的相关性 比如多个 key 代表一个对象,每个 key 是对象的一个属性,这种可直接按照特定对象的特征来设置一个新 Key——Hash 结构,原先的 key 则作为这个新 Hash 的 field。2.2.2 key 本身没有相关性 预估一下总量,预分一个固定的桶数量。比如现在预估 key 的总数为 2 亿,按照一个 hash 存储 100 个 field 来算,需要 2 亿 / 100 = 200W 个桶 (200W 个 key 占用的空间很少,2 亿可能有将近 20G ) 现在按照 200W 固定桶分就是先计算出桶的序号 hash(123456789) % 200W , 这里最好保证这个 hash 算法的值是个正数,否则需要调整下模除的规则; 这样算出(2021 年 3 月 27 日)
一文了解如何发现并解决 Redis 热 key 与大 key 问题
什么是热 key? 热 key 是服务端的常见问题,指一段时间内某个 key 的访问量远远超过其他的 key,导致大量访问流量落在某一个 redis 实例中;或者是带宽使用率集中在特定的 key(例如,对一个包含 2000 个 field 的 hash key 每秒发送大量的 hgetall 操作请求);又或者是 cpu 使用时间占比集中在特定的 key(例如,对一个包含 10000 个 field 的 key 每秒发送大量的 zrange 操作请求)。以被请求频率来定义是否是热 key,没有固定经验值。某个 key 被高频访问导致系统稳定性变差,都可以定义为热 key。可能造成的问题 热点缓存会导致流量集中,redis 缓存与数据库被击穿,从而引发系统雪崩。请求分配不均,存在热 key 的节点面临较大的访问压力,可能出现该数据分片的连接数被耗尽甚至宕机。(即使采取扩容也会对资源有很大的浪费) 发现方法 由于热 key 发生对系统稳定性有巨大危害,所以需要上线前设立故障预案、建立监控和报警机制,以便快速响应故障。根据业务经验,预估哪些是热 key。优点:简单直接。缺点:但并不是所有业务都能预估出哪些 key 是热 key。在客户端收集。在操作 redis 之前,加上统计频次的逻辑,然后将统计数据发送给一个聚合计算的服务进行统计。优点:方案简单。缺点:无法支持大公司多语言环境的 SDK,或者说多语言 SDK 对齐比较困难。此外 SDK 的维护升级成本会很高。在 proxy 层收集。有些服务在请求 redis 之前会请求一个 proxy 服务,这种场景可以使用在 proxy 层收集热 key 数据,收集机制类似于在客户端收集。优点:方案对使用方完全透明;没有 SDK 多语言异构和升级成本高的问题。缺点:并不是所有场景都会有 proxy 层。redis 集群监控。如果出现某个实例 qps 倾斜,说明可能存在热 key。优点:不需要额外开发。缺点:每次发生状况需要人工排查,因为热 key 只是导致 qps 倾斜的一种可能。redis 4.0 版本之后热点 key 发现功能。执行 redis-cli 时加上–-hotkeys 选项即可。优点:不需要额外开发。(资料日期为 2026 年 4 月 13 日)
Redis 热点 Key 发现及常见解决方案
热点 Key 问题产生的原因大致有以下两种:1、用户消费的数据远大于生产的数据 (热卖商品、热点新闻、热点评论、明星直播)。在日常工作生活中一些突发的的事件,例如:双十一期间某些热门商品的降价促销,当这其中的某一件商品被数万次点击浏览或者购买时,会形成一个较大的需求量,这种情况下就会造成热点问题。同理,被大量刊发、浏览的热点新闻、热点评论、明星直播等,这些典型的读多写少的场景也会产生热点问题。2、请求分片集中,超过单 Server 的性能极限。在服务端读数据进行访问时,往往会对数据进行分片切分,此过程中会在某一主机 Server 上对相应的 Key 进行访问,当访问超过 Server 极限时,就会导致热点 Key 问题的产生。热点 Key 问题的危害 1、流量集中,达到物理网卡上限。2、请求过多,缓存分片服务被打垮。3、DB 击穿,引起业务雪崩。如前文讲到的,当某一热点 Key 的请求在某一主机上超过该主机网卡上限时,由于流量的过度集中,会导致服务器中其它服务无法进行。如果热点过于集中,热点 Key 的缓存过多,超过目前的缓存容量时,就会导致缓存分片服务被打垮现象的产生。当缓存服务崩溃后,此时再有请求产生,会缓存到后台 DB 上,由于 DB 本身性能较弱,在面临大请求时很容易发生请求穿透现象,会进一步导致雪崩现象,严重影响设备的性能。解决方案 通常的解决方案主要集中在对客户端和 Server 端进行相应的改造。1、服务端缓存方案 首先 Client 会将请求发送至 Server 上,而 Server 又是一个多线程的服务,本地就具有一个基于 Cache LRU 策略的缓存空间。当 Server 本身就拥堵时,Server 不会将请求进一步发送给 DB 而是直接返回,只有当 Server 本身畅通时才会将 Client 请求发送至 DB,并且将该数据重新写入到缓存中。此时就完成了缓存的访问跟重建。但该方案也存在以下问题:1、缓存失效,多线程构建缓存问题 2、缓存丢失,缓存构建问题 3、脏读问题 2、使用 Memcache、Redis 方案 该方案通过在客户端单独部署缓存的方式来解决热点 Key 问题。使用过程中 Client 首先访问服务层,再对同一主机上的缓存层进行访问。该种解决方案具有就近访问、速度快、没有带宽限制的优点,但是同时也存在以下问题。1、内存资源浪费 2、脏读问题 3、使用本地缓存方案 使用本地缓存则存在以下问题:1、需要提前获知热点 2、缓存容量有限 3、不一致性时间增长 4、热点 Key 遗漏 传统的热点解决方案都存在各种各样的问题,那么究竟该如何解决热点问题呢?(来自 2018 年 12 月 19 日的资料)
FAQ
什么是 Redis 热点 Key?
热 key 是服务端的常见问题,指一段时间内某个 key 的访问量远远超过其他的 key,导致大量访问流量落在某一个 redis 实例中。
热点 Key 会造成什么危害?
热点缓存会导致流量集中,redis 缓存与数据库被击穿,从而引发系统雪崩。请求分配不均,存在热 key 的节点面临较大的访问压力,可能出现该数据分片的连接数被耗尽甚至宕机。
如何通过配置发现热点 Key?
执行 redis-cli 时加上–-hotkeys 选项即可。优点是不需要额外开发。或者在客户端收集,在操作 redis 之前,加上统计频次的逻辑。