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

ops/2025/1/8 20:47:56/

        Redis中的热点Key问题是指某些特定的Key被频繁访问,导致Redis中某个节点(或实例)承担过高的压力,可能引发性能瓶颈,甚至若缓存承受不住服务压力挂掉后,仍有大量请求时直接打到DB上,由于DB层相对缓存层查询性能更弱,在面临大请求时很容易发生DB雪崩现象,严重影响业务。

1. 什么样的Key被称为热点Key

通常以Key被请求频率来判定,目前没有具体的固定的数值来衡量,但有相关参考标准:

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

2. 解决方案

  • 热点key拆分

        热点Key问题是由于某个(或某些)Key被频繁访问,因此最直接的解决方案是破坏热点Key的形成,将热点Key进行逻辑拆分,将一个热点key拆分为多个Key,通过逻辑分片的方式将请求分散到不同的Key上,从而避免集中访问。拆分方式有两种:全量拷贝和切片拷贝。

        有些场景可以将热点Key进行全量拷贝,比如主从复制架构下,将hot_key拆分成hot_key1、hot_key_2、hot_key_3等,它们之间的数据是一致的,不同的请求都能访问到全量的数据。

        有些场景可以将热点Key进行拆分,hot_key1、hot_key_2、hot_key_3各存储hot_key的一部分数据

        实现方式如下:

        数据写入时:

  • 将热点 Key 拆分为 key_1key_2key_3 等多个 Key。
  • 访问时通过随机选择、哈希映射等方式确定具体的分片 Key。

数据读取时:

        聚合所有分片数据,返回合并后的结果。

        使用本地缓存,如利用ehcache、GuavaCache等,甚至是一个HashMap都可以。在发现热Key以后,把热Key加载到系统的JVM中,针对这种热Key请求,会直接从本地缓存中取,而不会直接请求redis;非热点Key直接走Redis缓存

  • 读写分离

        在主从复制模式下,从库会存储主库的所有数据包括热点Key,因此通过主从的读写分离,将读请求负载均衡分发到不同的从节点上,从而降低单节点的压力

  • 高并发优化

        对于频繁的写操作如计数器累加等,可以通过批量合并多个请求来减少Redis的访问频率。

  • 限流和降级(兜底方案)

        为防止发生热点Key问题时造成服务不可能等严重问题,可在热点Key访问过高时,进行应用限流,限制访问频率,减少对Redis的访问,甚至有必要时返回降级的数据(可通过配置文件自行定义)或空值

3. 如何发现及预防热点Key

  • 根据业务经验进行分析(推荐)

        主要根据业务场景进行分析,通过经验来判断哪些Key可能会成为热点Key,比如秒杀活动、演唱会门口、热搜新闻等。但是并不是每个热key都能被准确的预测,如对于电商平台来说,商家什么时候会上架相对火爆的秒杀活动就很难预测了,但是可以借助对不同商家的历史活动的数据分析来做一定的参考。

  • Redis集群监控(依赖于集群,较推荐)

该方案依赖于Redis集群,在Redis集群架构下,查看集群中的哪个Redis出现QPS倾斜,而出现QPS倾斜的实例有极大可能存在热点Key。

  • 使用hotKey监控(不推荐)

        该命令为Redis 4.0后新引入的一个指令,需要扫描所有的Key,如果Key较多的话执行时间会很长,效率低下。

  • 客户端监控和收集(推荐)

        这个方式就是在操作Redis之前,加入一行代码进行数据统计,异步上报行为,如类似日志采集,将单次Redis命令的操作/结果/耗时等统计,异步消息发送给采集消息队列,缺点就是对代码造成入侵,一般可以交给中间件加在自己包的redis二方包中;如果有做的好一点的Daas平台,可以在proxy层做监控,业务无需感知,统一在Daas平台查看redis监控;


http://www.ppmy.cn/ops/148556.html

相关文章

23.行号没有了怎么办 滚动条没有了怎么办 C#例子

新建了一个C#项目,发现行号没有了。 想把行号调出来,打开项目,选择工具>选项> 如下图,在文本编辑器的C#里有一个行号,打开就可以了 滚动条在这里:

从零开始自搭SpringBoot项目 -- Qingluopay项目工程介绍

从零开始自搭项目 – QingLuoPay 一,为什么要从零开始自搭项目 首先在介绍这个项目之前先介绍一下我为什么要选择从零自搭项目,而不是跟着网上哪些视频等做项目。 之前的很长一段时间我也都是在网上找一些做项目的视频就包含黑马的(神领物…

Cursor实现go项目配置并实现仓库Gin项目运行

✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏:知识备份 ✨特色专栏:知识分享 &#x…

window11 wsl mysql8 错误分析:1698 - Access denied for user ‘root‘@‘kong.mshome.net‘

🚨 错误分析:1698 - Access denied for user rootkong.mshome.net 这个错误是因为 MySQL 的 root 用户 使用 auth_socket 插件进行身份验证,而不是使用密码。因此,当你尝试从 远程主机 连接时,MySQL 会拒绝访问。 ✅ …

Transformer 和 Attention机制入门

1. 什么是 Transformer 背景: 在自然语言处理领域,早期常使用循环神经网络(RNN)及其变体(如 LSTM、GRU)来处理序列数据,如机器翻译、文本生成等任务。然而,RNN 结构存在以下问题&…

C# 中的命名空间与Java和Python中的导入

在 C#、Java 和 Python 这三种语言中,命名空间和导入机制都是用来组织和管理代码及其依赖的工具,但它们在具体实现和使用方式上存在一些差异。 1、问题背景 在 Java 和 Python 世界中,我们可以通过查看源文件来了解所有导入的来源&#xff0…

CSS进阶和SASS

目录 一、CSS进阶 1.1、CSS变量 1.2、CSS属性值的计算过程 1.3、做杯咖啡 1.4、下划线动画 1.5、CSS中的混合模式(Blending) 二、SASS 2.1、Sass的颜色函数 2.2、Sass的扩展(extend)和占位符(%)、混合(Mixin) 2.3、Sass的数学函数 2.4、Sass的模块化开发 2.5、Sass…

解决报错net.sf.jsqlparser.statement.select.SelectBody

在我们项目集成mybatis-plus时,总会遇到奇奇怪怪的报错,比如说下面的这个报错 而这个报错,是告诉我们的分页依赖冲突,要加个jsqlparser依赖来解决这个冲突,也相当于平衡,但是可能因为我们版本的不匹配,还是会报错,例如下面这样 但是我们是不知道到底是什么依赖冲突的,这个时候就…