【redis】热点key问题

【redis】热点key问题

  • 【一】什么是热点key问题
  • 【二】什么样的key被称为热key
  • 【三】热点Key问题的危害
  • 【四】如何监控发现热点key
  • 【五】热点Key的解决方案
    • 【1】使用二级缓存
    • 【2】将热key分散到不同的服务器中
    • 【3】热key拆分
    • 【4】将核心/非核心业务做Redis的隔离
  • 【六】业界已有的成熟解决方案
    • 【1】监控热key
    • 【2】通知系统做处理
    • 【3】如何保证缓存一致性

其实热key问题说来也很简单,就是瞬间有大量的请求去访问redis上某个固定的key,Redis会根据key分配哈希槽,而在Redis节点数不变的情况下,每个节点分配的哈希槽范围一般是不变的,因此导致这么多对于单个固定key的请求打在了一台redis节点上,从而压垮缓存服务的情况;

【一】什么是热点key问题

热key问题就是某个瞬间有大量的请求去访问Redis上某个固定的key,导致缓存击穿,请求都打到了DB上,压垮了缓存服务和DB服务,从而影响到应用服务可用的可用性;

被大量刊发、浏览的热点新闻、热点评论、明星直播等,这些典型的读多写少的场景就会产生热点key问题;相对DB,Redis的查询性能会高不少,但是再好的查询性能也是有阈值的。Rdis单节点的查询性能一般在2W的QPS,因此,对于单个固定key的查询不能超过这个值;

在服务端读数据进行访问时,往往会对数据进行分片切分(Redis的哈希槽),此过程中会在某一Redis节点主机Server上对相应的Key进行访问,当访问超过该节点Server的极限时,就会导致热点Key问题的产生;

【二】什么样的key被称为热key

通常以Key被请求频率来判定,目前没有很具体的数值来定义热key,但是下面的示例可以做一个参照,如:

(1)QPS集中在特定的Key:Redis实例的总QPS(每秒查询率)为2W,而其中一个Key的每秒访问量达到了1W以上;

(2)带宽使用率集中在特定的Key:对一个拥有上千个成员且总大小为1MB以上的HASH Key,每秒发送大量的HGETALL操作请求;

(3)CPU使用时间占比集中在特定的Key:对一个拥有数万个成员的Key(ZSET类型)每秒发送大量的ZRANGE操作请求;

【三】热点Key问题的危害

Redis的热点key出现时,往往会带来较大的危害和隐患;

(1)流量集中,达到物理网卡上限
当某一热点Key的请求在某一节点所在的主机上超过该主机网卡流量上限时,由于流量的过度集中,会导致该节点的服务器中其它服务无法进行;

(2)请求过多,缓存分片服务被打垮
上面也也介绍过,Redis单点查询性能是有限的,当热点key的查询超过Redis节点的性能阈值时,请求会占用大量的CPU资源,影响其他请求并导致整体性能降低;严重时会导致缓存分片服务被打垮,表现形式之一就是Redis节点自重启,此时该节点存储的所有key的查询都是不可用状态,会把影响辐射到其他业务上;

(3)集群架构下,产生访问倾斜
即某个数据分片被大量访问,而其他数据分片处于空闲状态,可能引起该数据分片的连接数被耗尽,新的连接建立请求被拒绝等问题;

(4)DB 击穿,引起业务雪崩
在这里插入图片描述

热Key的请求压力数量超出Redis的承受能力易造成缓存击穿,当缓存挂掉时,此时再有请求产生,可能直接把大量请求直接打到DB层上,由于DB层相对缓存层查询性能更弱,在面临大请求时很容易发生DB雪崩现象,严重影响业务;

在抢购或秒杀场景下,可能因商品对应库存Key的请求量过大,超出Redis处理能力造成超卖。

【四】如何监控发现热点key

(1)凭借业务经验,进行预估哪些是热key
其实这个方法还是挺有可行性的,比如某一个整点秒杀活动,活动信息的key、存放头部楼层的秒杀商品的信息的key一般就是热点key;但是并不是每个热key都能被准确的预测,如对于电商平台来说,商家什么时候会上架相对火爆的秒杀活动就很难预测了,但是可以借助对不同商家的历史活动的数据分析来做一定的参考;

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

(3)用redis自带命令
1-monitor命令:该命令可以实时抓取出redis服务器接收到的命令,然后写代码统计出热key是啥;当然,也有现成的分析工具可以给你使用,比如redis-faina;但是该命令在高并发的条件下,有内存增暴增的隐患,还会降低redis的性能。

2-hotkeys参数:redis 4.0.3提供了redis-cli的热点key发现功能,执行redis-cli时加上–hotkeys选项即可;但是该参数在执行的时候,如果key比较多,执行起来比较慢;参考:Redis 4.0热点Key查询方法;

这个方法是理论上可行的,但是一般公司是不允许直接连接redis节点自己输入命令的,而是直接通过Daas平台查看热点key的分析和监控;

【五】热点Key的解决方案

从上面的Redis的热点key的产生的原因以及危害,实战中可以有以下几个解决思路;

【1】使用二级缓存

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

本地缓存天然的将同一个key的大量请求,根据网络层的负载均衡,均匀分散到了不同的机器节点上,避免了对于固定key全部打到单个redis节点的情况,并且减少了1次网络交互;

当然,使用本地缓存不可避免的遇到的问题就是,对于要求缓存强一致性的业务来说,需要花费更多的精力在保证分布式缓存一致性上,会增加系统的复杂度;

【2】将热key分散到不同的服务器中

这个方案也很简单,不要让固定key老是走到同一台redis节点上;我们把这个key,在多个redis节点上都备份一份即可,在有热key请求进来的时候,我们就在有备份的redis上随机选取一台,进行访问取值,返回数据,就能缓解redis单点热key的查询压力;

因为redis是根据key分配哈希槽,因此在初始化时,可以将key拼接上随机尾缀,如下图的0-2N,生成的多个备份key散落在各个redis节点上,查询的时候也是随机拼接成这多个备份key中的一个,进行查询,从而让读写都不再集中于单个redis节点;

在这里插入图片描述
以上方法只是一种思路,把热key的值通过key尾缀,备份在不同的Redis节点上;如果真的想在每个Redis节点都备份热key,建议由Proxy层来完成,对客户端来说是无感知的,前提是公司的DBA团队比较给力,不然就需要自己去计算和维护;

当然,备份key方式也不可避免的要面对分布式缓存一致性问题,而redis本身的发布订阅功能刚好也能支持这一点,原key发生变更时,各个备份节点监听并完成同步,当然也可以遍历所有的备份key执行同步更新;

【3】热key拆分

热key问题的关键之一就是请求太多了,多的原因是热key存放的热点信息,对于每个用户请求过来时都需要查询,如零点秒杀活动信息,而单位时间的用户请求量是巨大的,从而对热key的查询请求量是巨大的;——因此解决热key的思路之一就是能否想办法把这个key给细化拆分,让不同用户请求的key是不一样的;

如秒杀活动场景,不同用户根据人群规则命中的活动策略ID可能是不同的,因此我们可以将整个活动元信息拆分成以策略为维度,把活动信息的key细化;这样请求过来时,根据用户人群策略,只会去找该策略绑定的活动信息的key,全量用户的对活动信息的查询请求会分散到不同的活动策略key上,从而避免固定key单点大量查询的问题;上面的随机尾缀也是类似的思路,即把固定key拆分或备份;

【4】将核心/非核心业务做Redis的隔离

Redis单点查询性能有限,当热点key的查询超过Redis节点的性能阈值时,会导致缓存分片服务被打垮现象的产生,此时当前节点上的所有业务的redis的读写都是不可用的;为了防止热点key引发问题时,核心业务不受影响,应当提前做好核心/非核心业务的Redis的隔离,至少热点key存在的redis集群应当与核心业务隔离开来;

【六】业界已有的成熟解决方案

其实方案的核心只有两步:1. 系统持续监控热点key;2. 发现热点key时发出通知做相应处理;有赞出过一篇《有赞透明多级缓存解决方案(TMC)》,里头也有提到热点key问题,我们刚好借此说明;

介绍一个方案之前先来看看为什么要设计这个方案——即他是来解决哪些痛点的?

使用有赞服务的电商商家数量和类型很多,商家会不定期做一些“商品秒杀”、“商品推广”活动,导致“营销活动”、“商品详情”、“交易下单”等链路应用出现缓存热点访问的情况:

(1)活动时间、活动类型、活动商品之类的信息不可预期,导致缓存热点访问情况不可提前预知;
(2)缓存热点访问出现期间,应用层少数热点访问key产生大量缓存访问请求:冲击分布式缓存系统,大量占据内网带宽,最终影响应用层系统稳定性;

为了应对以上问题,需要一个能够自动发现热点并将热点缓存访问请求前置在应用层本地缓存的解决方案,这就是TMC产生的原因;以下是系统架构;
在这里插入图片描述
(1)Jedis-Client:Java应用与缓存服务端交互的直接入口,接口定义与原生Jedis-Client无异;
(2)Hermes-SDK:自研“热点发现+本地缓存”功能的SDK封装,Jedis-Client通过与它交互来集成相应能力;
(3)Hermes 服务端集群:接收Hermes-SDK上报的缓存访问数据,进行热点探测,将热点key推送给Hermes-SDK做本地缓存;
(4)缓存集群:由代理层和存储层组成,为应用客户端提供统一的分布式缓存服务入口;
(5)基础组件:etcd集群、Apollo配置中心,为TMC提供“集群推送”和“统一配置”能力;

【1】监控热key

在监控热key方面,有赞用的是——在客户端进行收集。在《有赞透明多级缓存解决方案(TMC)设计思路》中有一句话提到

“TMC 对原生jedis包的JedisPool和Jedis类做了改造,在JedisPool初始化过程中集成TMC“热点发现”+“本地缓存”功能Hermes-SDK包的初始化逻辑。”

也就说他改写了jedis原生的jar包,加入了Hermes-SDK包,目的就是做热点发现和本地缓存;

从监控的角度看,该包对于Jedis-Client的每次key值访问请求,Hermes-SDK 都会通过其通信模块将key访问事件异步上报给Hermes服务端集群,以便其根据上报数据进行“热点探测”。热点发现的流程如下:

在这里插入图片描述

【2】通知系统做处理

在处理热key方案上,有赞用的是二级缓存;

有赞在监控到热key后,Hermes服务端集群会通过各种手段通知各业务系统里的Hermes-SDK,告诉他们:“老弟,这个key是热key,记得做本地缓存。” 于是Hermes-SDK就会将该key缓存在本地,对于后面的请求;Hermes-SDK发现这个是一个热key,直接从本地中拿,而不会去访问集群;通知方式各种各样,这篇文章文只是提供一个思路;

【3】如何保证缓存一致性

再补充下有赞使用二级缓存时如何保证缓存一致性的;
(1)Hermes-SDK的热点模块仅缓存热点key数据,绝大多数非热点key数据由缓存集群存储;
(2)热点key变更导致value失效时,Hermes-SDK同步失效本地缓存,保证本地强一致;
(3)热点key变更导致value失效时,Hermes-SDK通过etcd集群广播事件,异步失效业务应用集群中其他节点的本地缓存,保证集群最终一致;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/57326.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nature 正刊丨细菌免疫蛋白直接感知两种不同的噬菌体蛋白

01摘要 真核先天免疫系统使用模式识别受体通过检测病原体相关的分子模式来感知感染,然后触发免疫反应。细菌也进化出了类似的免疫蛋白,可以感知其病毒捕食者的某些成分,即噬菌体1,2,3,4,5,6。尽管不同的免疫蛋白可以识别不同的噬菌体编码的触…

log4j2.xml

log4j2.xml 1、log4j2.xml使用2、日志器的流程解析2.1、几个重要的类2.2、整体流程图 3、部分源码3.1、通过简单例子看源码3.2、log4j2.xml配置指导 如侵权&#xff0c;请联系&#xff0c;无心侵权&#xff5e; 如有错误&#xff0c;也请指正。 1、log4j2.xml使用 <?xml v…

Anaconda虚拟环境安装cuda和pytorch

首先电脑上要有Anaconda&#xff0c;使用conda创建一个虚拟环境,并激活 conda create yolov8 conda activate yolov8winR输入cmd&#xff0c;在命令窗口输入 NVIDIA-smi可以查看到自己电脑支持的cuda环境&#xff0c;如下图 再打开torch的官网 pytorch官网 查看目前支持的版…

目标检测——Cascade R-CNN算法解读

论文&#xff1a; Cascade R-CNN: Delving into High Quality Object Detection (2017.12.3) 链接&#xff1a;https://arxiv.org/abs/1712.00726 Cascade R-CNN: High Quality Object Detection and Instance Segmentation (2019.6.24) 链接&#xff1a;https://arxiv.org/abs…

Z 字形变换(6)

这道题之前一直不会做&#xff0c;明白他是什么意思&#xff0c;但是找不到方法或者方法过于繁琐 方法1&#xff1a; 这是我在力扣评论区看到的方法&#xff0c;太精彩了。 虽然我实现起来效率并不高&#xff0c;可能是我代码的问题&#xff0c;但是他的思路很巧妙。 字符串的…

Spring--1

spring是一个轻量级的&#xff0c;采用IOC与AOP编程思想的java后端开发框架&#xff0c;简化了企业级的应用开发。 Spring体系 数据访问层&#xff0c;Web层&#xff0c;配置中心&#xff0c;测试区 IOC 控制反转&#xff0c;将创建对象的控制权交由Spring框架&#xff0c;需…

音频分割:长语音音频 分割为 短语音音频 - python 实现

在做语音任务时&#xff0c;有是会用到的语音音频是长音频&#xff0c;这就需要我们将长音频分割为短音频。 该示例将声音的音量和静默时间结合作为语音的分割条件。 使用音量和静默时间结合的分割条件&#xff0c;能够比较好的进行自然断句&#xff0c;不会话语没有说完就切断…

Spring声明式事务管理:深入探索XML配置方式

前言 Spring的事务管理&#xff0c;无论是基于xml还是注解实现&#xff0c;本质上还是实现数据库的事务管理机制&#xff0c;因此要注意发送SQL的连接是否为同一个&#xff0c;这是实现声明式事务的关键。 以下案例和实现基于SSM整合框架完成&#xff0c;不知道如何整合SSM&…

【K8S系列】Kubernetes Pod 状态详细介绍及异常状态解决方案

在 Kubernetes 中&#xff0c;Pod 是最小的可调度单元&#xff0c;负责运行一个或多个容器。Pod 的状态能够反映其生命周期中的不同阶段&#xff0c;帮助用户了解当前的运行状况。本文将详细介绍 Kubernetes Pod 的各种状态及其可能的异常状态解决方案。 一、Pod 状态概览 Po…

查缺补漏----数据结构树高总结

① 对于平衡二叉树而言&#xff0c;树高的规律&#xff1a; 高度为h的平衡二叉树的含有的最少结点数&#xff08;所有非叶节点的平衡因子均为1&#xff09;&#xff1a; n01&#xff0c;n11&#xff0c;n22 含有的最多结点数&#xff1a; (高度为h的满二叉树含有的结点数) ②…

Flutter在 iOS 中实现无弹窗获取剪切板内容

前言 在最新的项目需求中&#xff0c;我们需要在获取剪切板内容时避免弹出授权提示。这一功能是基于竞品的实现&#xff0c;旨在优化用户体验&#xff0c;特别是在推广获取跳转链接的场景下非常有用。 解决方案 通过查阅资料&#xff0c;我们发现对于 iOS 16 及以上的系统&a…

Fusion创建一个简单的api脚本文件

我的Fusion版本&#xff1a;Fusion 2.0.20476 x86_64 脚本模块在实用程序->附加模型->脚本和附加模块&#xff0c;快捷键为shifts 里面有一些演示脚本&#xff0c;可以直接使用 也可以自己创建一个新的脚本 创建的脚本在此处—— 选择脚本文件&#xff0c;点击编辑&a…

Unity Mirror NetworkManager初识

文章目录 Network Manager网络管理器什么是网络管理器&#xff1f;通过Transports进行定制化网络连接管理自定义连接地址和端口号Game State Management游戏状态管理Network Manager HUD玩家预制体及其生成控制Spawn Prefabs其他预制体注册Scene Management场景管理 Network Ma…

在Windows系统中,cmd 查看 MongoDB 相关信息

MongoDB是一种流行的NoSQL数据库&#xff0c;广泛应用于各种现代应用程序中。 1 查看MongoDB的版本号 要查看MongoDB的版本号&#xff0c;可以使用mongo命令连接到MongoDB&#xff0c;然后执行db.version()。 mongo连接到数据库后&#xff0c;执行以下命令&#xff0c;输出M…

读数据工程之道:设计和构建健壮的数据系统16源系统实际细节(下)

1. 数据共享 1.1. 云数据共享的核心概念是&#xff0c;多租户系统支持租户之间共享数据的安全策略 1.2. 任何具有细粒度权限系统的公有云对象存储系统都可以成为数据共享的平台 1.3. 数据共享也简化了数据市场的概念&#xff0c;在几个流行的云和数据平台上都可用 1.4. 数据…

RabbitMQ系列学习笔记(三)--工作队列模式

文章目录 一、工作队列模式原理二、工作队列模式实战1、抽取工具类2、消费者代码3、生产者代码4、查看运行结果 本文参考 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq RabbitMQ 详解 Centos7环境安装Erlang、RabbitMQ详细过程(配图) 一、工作队列模式原理 与简单模式相…

SpringBoot篇(二、制作SpringBoot程序)

目录 一、代码位置 二、四种方式 1. IDEA联网版 2. 官网 3. 阿里云 4. 手动 五、在IDEA中隐藏指定文件/文件夹 六、复制工程-快速操作 七、更改引导类别名 一、代码位置 二、四种方式 1. IDEA联网版 2. 官网 官网制作&#xff1a;Spring Boot 3. 阿里云 阿里云版制…

基于SSM+微信小程序的家庭记账本管理系统(家庭1)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 1、管理员端功能有首页、个人中心、用户管理&#xff0c;消费详情管理、收入详情管理、系统管理等。 2、用户端功能有首页、消费详情、收入详情、论坛信息、我的等功能。 2、项目技术 …

django5入门【02】创建新的django程序

注意&#xff1a; ⭐前提&#xff1a;已经安装了python以及django所依赖的包1、通过django-admin管理工具在命令行创建Django应用程序&#xff0c;创建命令如下&#xff1a; django-admin startproject ProjectName❓ 疑问&#xff1a;除了使用命令行创建django程序外&#x…

OCR经典神经网络(三)LayoutLM v2算法原理及其在发票数据集上的应用(NER及RE)

OCR经典神经网络(三)LayoutLM v2算法原理及其在发票数据集上的应用(NER及RE) LayoutLM系列模型是微软发布的、文档理解多模态基础模型领域最重要和有代表性的工作&#xff1a; LayoutLM v2&#xff1a;在一个单一的多模态框架中对文本&#xff08;text&#xff09;、布局&…