Redis集群热点Key问题解决方案

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

一、热点Key的发现

1. 监控工具发现

  • Redis内置命令
    使用redis-cli --hotkeys命令(需开启LFU算法)直接识别高频访问Key。
    redis-cli --hotkeys
    # 输出示例
    # Hot key 'product:1001' found with 15234 accesses
    
  • Redis监控命令
    通过INFO commandstats统计命令调用频率,间接发现热点Key。
    > INFO commandstats
    cmdstat_get:calls=23456,usec=123456,usec_per_call=5.27
    

2. 客户端埋点

  • SDK集成
    在客户端代码中嵌入统计逻辑,记录每个Key的访问次数。

    // Java示例:使用AOP统计Key访问
    @Around("execution(* com.xxx.RedisClient.get(..))")
    public Object trackKeyAccess(ProceedingJoinPoint pjp) {
        String key = (String) pjp.getArgs()[0];
        Metrics.counter("redis_key_access", "key", key).increment();
        return pjp.proceed();
    }
    
  • 代理层统计
    在代理中间件(如Twemproxy)中增加流量分析模块。

    # Python伪代码:代理层Key统计
    def handle_request(key):
        stats[key] = stats.get(key, 0) + 1
        if stats[key] > 10000:
            alert_hot_key(key)
    

二、热点Key解决方案

1. 本地缓存(客户端缓存)

  • 方案原理
    在应用层对热点Key进行本地缓存,减少对Redis的直接访问。

  • 实施步骤

    1. 使用Guava/Caffeine实现本地缓存
      LoadingCache<String, String> localCache = Caffeine.newBuilder()
          .maximumSize(10_000)
          .expireAfterWrite(1, TimeUnit.MINUTES)
          .build(key -> redisClient.get(key));
      
    2. 设置合理的过期时间(如1-5秒)
    3. 结合发布订阅机制实现缓存失效通知
  • 适用场景
    读多写少的热点Key(如商品详情)

2. Key分片(Sharding)

  • 方案原理
    将单个Key拆分为多个子Key,分散到不同节点。

  • 实施步骤

    1. 原始Key:product:1001

    2. 拆分规则:

      public class ShardingRedisClient {
         private RedisClient originalClient; // 原客户端
         private HotKeyDetector hotKeyDetector; // 热点检测器
         private ShardingRouter shardingRouter; // 分片路由器
      
         public String get(String key) {
             // 1. 判断是否为热点Key
             if (hotKeyDetector.isHotKey(key)) {
                 // 2. 动态生成分片Key
                 String shardKey = shardingRouter.getShardKey(key);
                 return originalClient.get(shardKey);
             } else {
                 return originalClient.get(key);
             }
         }
         
         public void set(String key, String value) {
             // 1. 写入原始Key
             originalClient.set(key, value);
             
             // 2. 如果是热点Key,同时写入分片Key
             if (hotKeyDetector.isHotKey(key)) {
                 String shardKey = shardingRouter.getShardKey(key);
                 originalClient.set(shardKey, value);
             }
         }
      
      }
      
    3. 客户端聚合查询结果

  • 优化变体

    // 时间窗口分片(适用于秒杀场景)
    String shardKey = "product:1001:" + System.currentTimeMillis()/1000;
    

3. 集群分片优化

  • 方案原理
    利用Redis Cluster特性强制Key分布。

  • 实施步骤

    1. 使用Hash Tag强制Key分布
      # 将相关Key分配到同一slot
      product:{1001}:info
      product:{1001}:stock
      
    2. 通过CLUSTER KEYSLOT命令验证分布
      > CLUSTER KEYSLOT "product:{1001}:info"
      (integer) 5432
      

4. 读写分离

  • 方案原理 : 利用从节点分担读压力。

  • 实施步骤

    1. 配置Redis Cluster读写分离
      // Lettuce客户端配置
      ClusterClientOptions options = ClusterClientOptions.builder()
          .readFrom(ReadFrom.REPLICA_PREFERRED)
          .build();
      
    2. 对热点Key启用强制读主节点机制
      if(isHotKey(key)) {
          readFromMaster(key);
      }
      

5. 限流降级

  • 方案原理 :对热点Key的访问进行流量控制。

6. 业务逻辑优化

  • 方案原理 :从业务层面减少对单一Key的依赖。

  • 实施案例

    1. 合并操作
      将多次GET合并为MGET
      MGET user:1001:name user:1001:email user:1001:phone
      
    2. 异步更新
      使用消息队列异步处理写操作
      redisClient.setAsync("product:1001", value);
      

三、方案对比与选型

方案优点缺点适用场景
本地缓存响应快,减少网络消耗数据一致性难保障读多写少的静态数据
Key分片分散压力效果显著客户端逻辑复杂化可水平拆分的业务数据
集群分片优化利用原生集群特性需要重新设计Key结构关联Key需要集中存储的场景
读写分离充分利用集群资源主从延迟可能影响一致性读远大于写的场景
限流降级系统保护效果立竿见影可能影响用户体验突发流量场景
业务逻辑优化根治性问题解决改造成本较高所有场景的长期优化

四、实战建议

  1. 监控先行
    部署Prometheus+Granafa监控体系,设置关键指标告警:

    # Prometheus告警规则示例
    - alert: HotKeyDetected
      expr: rate(redis_key_access_count[5m]) > 1000
      for: 2m
    
  2. 组合使用
    典型秒杀场景方案组合:

    • 本地缓存(1秒过期)
    • Key分片(按时间窗口拆分)
    • 令牌桶限流(QPS=5000)
  3. 动态调整
    通过配置中心实现热更新:

    // Apollo配置监听示例
    @ApolloConfigChangeListener
    public void onHotKeyConfigChange(ConfigChangeEvent event) {
        if(event.isChanged("hotkey.config")) {
            reloadHotKeyRules();
        }
    }
    

通过以上方案的系统性实施,可有效应对Redis集群中的热点Key问题,保障系统的高可用性。

Redis缓存热点引发的思考 01—背景 一开始并没有打算梳理redis的相关内容,因为在一篇文章中看到关于热点问题的处理,心中有一些疑惑,内容如下: 缓存热点: 对于特别热的数据,如果大部分甚至所有的业务都命中同一份缓存数据,则这份数据所在缓存服务器压力就很大,例如,某明星微博发布“我们”来宣告恋爱了,则短时间内有成千上万的用户都来围观。 缓存热点解决方案: 就是复制多份缓存,将请求分散到多个缓存服务器上,减轻缓存热点导致的单台缓存服务器压力,以新浪微博为例,对于粉丝超过100万的明星,每一条微博都可以生成100分缓存. 阅读详情

相关推荐

Redis集群热点Key解决方案

解决 Redis 热点 Key 问题,核心思路是分散压力、削峰填谷、动态调整。分散机制:(伪 Key 扩展、一致性哈希)。冷热分离:(多层缓存架构、本地缓存补充)。动态守护:(实时监控、影子缓存)。减少重复访问:(请求合并、随机延时)。对于复杂场景,可以结合多种方法,比如热点 Key 的本地缓存和随机伪 Key 扩展结合使用,将热点请求分散并处理到底层缓存以外。

互联网架构师笔记 308

redis热点key的解决

1、如果热点key的QPS过高,单机是扛不住的,要做一个(主库用来写,从库用来读),再加一个从库。2、但是如果热key本身的数量是比较少的,可以考虑做一个,可以添加一个本地缓存。本地缓存也是一个最常用的解决方案,既然我们的一级缓存扛不住这么大的压力,就再加一个二级缓存吧。由于每个请求都是由service发出的,这个二级缓存加在service端是再合适不过了,因此可以在服务端每次获取到对应热key时,使用本地缓存存储一份,等本地缓存过期后再重新请求,降低redis集群压力。

PnJgHT的博客 2177

Redis缓存热点key问题解决方案

主要介绍了Redis缓存热点key问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

Redis——热点key问题

本篇主要介绍Redis中的热点Key问题,包括热点Key产生的原因、如何监控发现热点key以及热点Key解决方案

娜娜米的博客 1万+

redis热点key问题

key问题就是某个瞬间有大量的请求去访问Redis上某个固定的key,导致缓存击穿,请求都打到了DB上,压垮了缓存服务和DB服务,从而影响到应用服务可用的可用性;被大量刊发、浏览的热点新闻、热点评论、明星直播等,这些典型的读多写少的场景就会产生热点key问题;相对DB,Redis的查询性能会高不少,但是再好的查询性能也是有阈值的。Rdis单节点的查询性能一般在2W的QPS,因此,对于单个固定key的查询不能超过这个值;

weixin_44823875的博客 3197

Redis缓存key问题常用解决方案

前言        做一些C端业务,不可避免的要引入一级缓存来代替数据库的压力并且减少业务响应时间,其实每次引入一个中间件来解决问题的同时,必然会带来很多新的问题需要注意,比如上篇文章《数据库缓存一致性实战》中提到的如何做缓存的一致性。那么其实还会有一些其他问题比如使用Redis作为一级缓存时可能带来的热key、大key问题,本文我们就热key(hot key问题来讨论,如何合理的解决热key问题。 正文 背景       &nbs

拾忆的博客 9250

如何解决Redis中的热点key问题

Redis中的是指某些特定的Key被频繁访问,导致Redis中某个节点(或实例)承担过高的压力,可能引发性能瓶颈,甚至若缓存承受不住服务压力挂掉后,仍有大量请求时直接打到DB上,由于DB层相对缓存层查询性能更弱,在面临大请求时很容易发生DB雪崩现象,严重影响业务。通常以Key被请求频率来判定,目前没有具体的固定的数值来衡量,但有相关参考标准: 热点Key问题是由于某个(或某些)Key被频繁访问,因此最直接的解决方案是破坏热点Key的形成,将热点Key进行逻辑拆分,将一个热点key拆分为多个Ke

weixin_43287459的博客 1334

如何处理redis集群中hot key和big key

概述 redis 集群部署方式大部分采用类 Twemproxy 的方式进行部署。即通过 Twemproxy 对 redis key 进行分片计算,将 redis key 进行分片计算,分配到多个 redis 实例中的其中一个。tewmproxy 架构图如下: 由于 Twemproxy 背后的多个 redis 实例在内存配置和 cpu 配置上都是一致的,所以一旦出现访问量倾斜或者数据量...

东境物语 2572

面试精讲之面试考点及大厂真题 - 分布式专栏 11 Redis热点key大Value解决方案

10 Redis雪崩,穿透,击穿三连问 能够生存下来的物种,并不是那些最强壮的,也不是那些最聪明的,而是那些对变化作出快速反应的。 ——达尔文 引言 关于Redis雪崩,穿透,击穿的问题,第一次接触名字有点陌生,听上去还比较相似,难以理解,过去做的很多项目中也都是用过Redis,但是第一次听到这几个关于Redis的坑还是一脸懵逼,直到这些坑真正显灵的时候才彻底意识...

YunWisdom 910

如何解决 Redis 数据倾斜、热点问题

Redis 集群 总共有4台机器,假设数据分布均衡,每台机器承担 四分之一的流量,如果某一台机器突然挂了,顺时针方向下一台机器将要承担这多出来的 四分之一 流量,最终要承担 二分之一 的流量,还是有点恐怖。由于业务数据特殊性,按照指定的分片规则,可能导致不同的实例上数据分布不均匀,大量的数据集中到了一台或者几台机器节点上计算,从而导致这些节点负载多大,而其他节点处于空闲等待中,导致最终整体效率低下。如果集群的机器不多,且平时单机的负载水位很高,某个节点宕机带来的压力很容易引发雪崩效应。

公众号:微观技术 2654

Redis的各种key问题

4.核心业务隔离:把热点key 和非核心业务隔离 保证及时redis宕机也不会影响其他业务。1.热key备份:加上随机后缀放到不同的节点 分散读写压力 但是可能要额外的同步机制。2.多级缓存:再加上一层本地缓存,单少redis的访问次数 需要额外的同步机制。5.redis集群 把大key拆分 散落到不同节点 在服务端再做拼接。1.业务层面:压根不应该把这么大的数据存在redis 要优化业务层。2.Redis单线程,操作大Key会造成阻塞 影响其他命令。4.把大对象拆分成不同的小对象 减少单个key的大小。

qq_52254412的博客 223

20250107面试鸭特训营第15天

20250107面试鸭特训营第15天

Again_acme的博客 963

如何解决RedisKey问题

如何解决Redis热点key问题

飞乐鸟的博客 1443

Redis热点Key独立集群实现方案

Redis热点Key独立集群实现方案摘要 本方案针对高并发场景下的Redis热点Key问题,提出将热点Key分离到独立集群解决方案。通过多实例配置、灵活的路由策略和统一访问接口,实现资源隔离和负载均衡。方案核心包括: 支持配置多个Redis实例(普通实例和热点实例) 提供多种路由规则(前缀匹配、正则匹配、哈希路由) 对外提供统一访问接口,屏蔽实例差异 通过配置扩展实现灵活部署 技术实现基于Redisson客户端,通过配置文件定义实例和路由规则,初始化时自动创建对应连接池并建立路由映射关系。该方案可有效缓解

weixin_43076660的博客 617

Redis笔记补充-热点数据、io多路复用、redis与mysql数据不一致问题

Redis热点数据的处理、过期删除策略、淘汰策略、Redis与MySQL数据不一致问题Redis IO多路复用、一些面试问题

m0_57098080的博客 1139

常见缓存问题处理-缓存热点key

希望通过本文,大家明白如何处理生产上遇到的热key问题

daobuxinzi的博客 724

RedisRedis分布式集群倾斜

0、背景 对于分布式系统而言,整个集群处理请求的效率和存储容量,往往取决于集群中响应最慢或存储增长最快的节点。所以在系统设计和容量规划时,我们尽量保障集群中各节点的“数据和请求分布均衡“。但在实际生产系统中,出现数据容量和请求倾斜(类似Data Skew)问题是比较常见的。 示例:春节抽奖服务,业务评估峰值qps是2w,转化到redis集群为10w qps和5GB内存存储,部署5个分片每个分片1GB+2W qps的redis集群(包含预留容量)。结果活动开始时,才发现服务存在”热点key",请求严重倾斜

Sunny的专栏 609
上一篇: 深入解析 Tomcat 线程管理机制:从设计思想到性能调优
下一篇: Redis集群大Key问题深度解决方案
fjkxyl
博客等级 码龄11年 340粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fjkxyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值