当前位置: 首页 > article >正文

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

        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。

数据读取时:

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

  • 使用二级缓存+Redis缓存

        使用本地缓存,如利用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.kler.cn/a/471292.html

相关文章:

  • Jmeter进阶篇(31)解决java.net.BindException: Address already in use: connect报错
  • 基于RedHat9部署WordPress+WooCommerce架设购物网站
  • [开源]自动化定位建图系统
  • stm32week3
  • 2024AAAI SCTNet论文阅读笔记
  • VS2022 C#创建Com组件和调用
  • Microsoft Azure Cosmos DB:全球分布式、多模型数据库服务
  • 设计模式--享元模式【结构型模式】
  • 【python】字符串元素的访问与截取
  • QT c++ 自定义按钮类 加载图片 美化按钮
  • LeetCode 3019.按键变更的次数:遍历(转小写)
  • selenium找不到元素解决方案-切换iframe
  • Bash语言的文件操作
  • HTML5-标签
  • Swin-Transformer
  • Web渗透测试之XSS跨站脚本攻击分类 详解
  • Effective C++读书笔记——item11(自赋值)
  • Python中判断语句及循环语句练习
  • 对于安装完服务后,无法执行命令的问题处理
  • 行为树详解(6)——黑板模式
  • halcon三维点云数据处理(五)创建代表工具和机器人底座的3D模型
  • Qt仿音乐播放器:客户端唯一化
  • 使用 httputils + chronicle-bytes 实现金融级 java rpc
  • 【免费】2004-2019年各省规模以上工业企业RD经费面板数据
  • RabbitMQ-死信队列
  • android系统的一键编译与非一键编译 拆包 刷机方法