人为制造redis的热key、大key引发的线上事故

2023-12-16

背景

Redis中间件,我们主要是用来做缓存,缓解数据库的访问压力,我们搭建的是redis集群

在一个风和日丽的下午,突然收到运维的报警信息

运维:小李,你们使用的redis中间件所在的服务器,有大量的流量流出,宽带快要占满了,网卡都冒烟了,严重影响其他服务,快速排查解决下,如果一时半会解决不了,我们只能kill掉redis的进程,避免影响其他服务

小李:我们立刻排查,有需要协助的,请你们帮忙

我们redis使用的是集群,三主三从,怎么才有一台流量这么大?大概率我估计是遇到了 大key、热key ,大key是存储的数据量大,热key访问频率高,分布还不均匀,才能导致单台机器流量非常大

先介绍下 热key、大key,让大家有个了解

问题的严重性

在使用Redis的过程中,如果未能及时发现并处理 大Key与热Key ,可能会导致服务性能下降、用户体验变差,甚至引发大面积故障。

大Key和热Key的定义

什么是BigKey

通常以Key的大小和Key中成员的数量来综合判定,例如:

  • Key本身的数据量过大:一个String类型的Key,它的值为5 MB。
  • Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10,000个。
  • Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的Value(值)总大小为100 MB。

什么是热key

通常以其接收到的Key被请求频率来判定,例如:

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

上述例子中的具体数值仅供参考,在实际业务中,您需要根据Redis的实际业务场景进行综合判断

大Key和热Key引发的问题

大key

  • 客户端执行命令的时长变慢。
  • Redis内存达到maxmemory参数定义的上限引发操作阻塞或重要的Key被逐出,甚至引发内存溢出(Out Of Memory)。
  • 集群架构下,某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡。
  • 对大Key执行读请求,会使Redis实例的带宽使用率被占满,导致自身服务变慢,同时易波及相关的服务。
  • 对大Key执行删除操作,易造成主库较长时间的阻塞,进而可能引发同步中断或主从切换。

热key

  • 占用大量的CPU资源,影响其他请求并导致整体性能降低。
  • 集群架构下,产生访问倾斜,即某个数据分片被大量访问,而其他数据分片处于空闲状态,可能引起该数据分片的连接数被耗尽,新的连接建立请求被拒绝等问题。
  • 在抢购或秒杀场景下,可能因商品对应库存Key的请求量过大,超出Redis处理能力造成超卖。
  • 热Key的请求压力数量超出Redis的承受能力易造成缓存击穿,即大量请求将被直接指向后端的存储层,导致存储访问量激增甚至宕机,从而影响其他业务。

大Key和热Key产生的原因

未正确使用Redis、业务规划不足、无效数据的堆积、访问量突增等都会产生大Key与热Key

大key

  • 不适用的场景下使用Redis,易造成Key的value过大,如使用String类型的Key存放大体积二进制文件型数据;
  • 业务上线前规划设计不足,没有对Key中的成员进行合理的拆分,造成个别Key中的成员数量过多;
  • 未定期清理无效数据,造成如HASH类型Key中的成员持续不断地增加;
  • 使用LIST类型Key的业务消费侧发生代码故障,造成对应Key的成员只增不减。

热key

预期外的访问量陡增,如突然出现的爆款商品、访问量暴涨的热点新闻、直播间某主播搞活动带来的大量刷屏点赞、游戏中某区域发生多个工会之间的战斗涉及大量玩家等。

我们的事故案例

通过上面的介绍,应该对大key、热key,有个了解了,那下面介绍下,我们排查问题的过程

找出热key、大key

思路一

redis 4.0版本以上提供了分析大key、热key的分析工具,前提是: 内存策略修改为 LFU 算法


  

js

复制代码

# 分析统计热key redis-cli --hotkeys # 分析统计大key redis-cli --bigkeys

以上两个命令,就可以分析线出线上的热key、大key。也是通过 scan 完成的,可能会对节点造成阻塞,同时bigkeys只能计算每种数据结构的 top1,如果有些数据结构有比较多的 Bigkey是查找不出来的,如下:

image.png

此方案暂时放弃,主要怕对节点造成阻塞

思路二

从业务角度出发,我们的系统有链路跟踪,使用的是pinpoint,通过pinpoint查看最近这段时间请求量高、响应慢的接口,找出top靠前的接口,找到接口对应的代码,进行分析,查找这些接口哪里调用了redis,使用的key,然后对key进行查看

image.png

通过接口代码分析,发现其中一个接口,for循环里面调用redis,获取值,伪代码如下:


  

Java

复制代码

public List getData(){ /** * 1、通过条件分页查询数据 * 2、对查询出来的数据,for循环去查询redis 的数据,然后对查询出来的数据,进行转换,再组装数据 * */ //查询业务数据 List<AccessLogEntity> list = new ArrayList<>(); for (AccessLogEntity accessLog : list) { String str = redisTemplate.opsForValue().get("key"); //json字符转换为对象 //对list的数据进行匹配 关联 // 组装数据 } return list; }

代码分析:

  1. key是固定的,应该放在循环外面调用一次,遍历的时候直接使用即可,这种人为的造成了 热key
  2. 对key进行分析,这个key到底多大,连接上reids 使用命令 MEMORY usage key 查看大小,结果发现这个key竟然有100Mb,再看这个key值的写入,是整张表的数据直接存在redis中,这是redis当数据库用了,人才啊真是人才,人为制造大key
  3. 根据业务场景,也不应该使用String,这种场景 使用hash是比较适合的

解决方案

临时解决线上问题

  1. 把获取调用redis的获取值的方法,放在循环体外,减少请求量
  2. redis获取的数据,放在本地缓存(比如:使用Map),持续减少请求量

通过以上两个修改,发布线上,持续观察,运维反馈:流量降下来了,服务正常了

后续优化

通过项目代码分析,这并不存在热key,是人为放在分页循环里面导致的,所以不考虑热key的问题,只需要把大key优化掉即可

我们使用hash替换String,并且key拆分为多个hash key,并确保每个Key的成员数量在合理范围

通过这个事故,也让我深究大key、热key的解决方案

优化大Key与热Key

大key优化方案

  • 对大Key进行拆分

    例如将含有数万成员的一个HASH Key拆分为多个HASH Key,并确保每个Key的成员数量在合理范围。在Redis集群架构中,拆分大Key能对数据分片间的内存平衡起到显著作用。

  • 对大Key进行清理

    将不适用Redis能力的数据存至其它存储,并在Redis中删除此类数据。

  • 对过期数据进行定期清理

    堆积大量过期数据会造成大Key的产生,例如在HASH数据类型中以增量的形式不断写入大量数据而忽略了数据的时效性。可以通过定时任务的方式对失效数据进行清理。

  • 监控Redis的内存水位 定期对redis内存分析 redis内存可视化分析 ,这里使用的是rdb,redis内存大于5G,建议使用 redis-rdb-tools ,根据自己的业务实际情况对大key的定义,做二次开发,超过设置的阈值,就报警提醒

热key优化方案

  • 在Redis集群架构中对热Key进行复制

    在Redis集群架构中,由于热Key的迁移粒度问题,无法将请求分散至其他数据分片,导致单个数据分片的压力无法下降。此时,可以将对应热Key进行复制并迁移至其他数据分片,例如将热Key foo复制出3个内容完全一样的Key并名为foo2、foo3、foo4,将这三个Key迁移到其他数据分片来解决单个数据分片的热Key压力。

  • 使用本地二级缓存

    当出现热 Key 以后,把热 Key 加载到系统的 JVM 中。后续针对这些热 Key 的请求,会直接从 JVM 中获取,而不会走到 Redis 层。这些本地缓存的工具很多,比如 Ehcache ,或者 Google Guava Cache 工具,或者直接使用 HashMap 作为本地缓存工具都是可以的。

image.png

这里有两个缺点:

  • 如果对热 Key 进行本地缓存,需要防止本地缓存过大,影响系统性能;
  • 需要处理本地缓存和 Redis 集群数据的一致性问题。

统一解决方案

京东hotkey 对任意突发性的无法预先感知的热点数据,包括并不限于热点数据(如突发大量请求同一个商品)、热用户(如恶意爬虫刷子)、热接口(突发海量请求同一个接口)等,进行毫秒级精准探测到。然后对这些热数据、热用户等,推送到所有服务端JVM内存中,以大幅减轻对后端数据存储层的冲击,并可以由使用者决定如何分配、使用这些热key(譬如对热商品做本地缓存、对热用户进行拒绝访问、对热接口进行熔断或返回默认值)。这些热数据在整个服务端集群内保持一致性,并且业务隔离

image.png

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

人为制造redis的热key、大key引发的线上事故 的相关文章

  • 如何在node.js中为相同的两个应用程序分离redis数据库

    我有两个相同的应用程序 一个用于演示 一个用于开发 并且我使用 redis 数据库来存储键值 我如何为这两个不同的应用程序分离 redis 数据库 我使用 Node js 作为 Redis 客户端 我用这个https github com
  • 如何在多线程应用程序中使用 StackExchange.Redis IDatabase 对象?

    我从 StackExchange Redis 文档中收到有关如何使用 IDatabase 的混合消息 在里面基本使用文档 https github com StackExchange StackExchange Redis blob mas
  • 在节点中使用redis获取hash key的所有字段和值

    红色是使用哈希 我需要存储具有多个字段和值的哈希键 我尝试如下 client hmset Table1 Id 9324324 ReqNo 23432 redis print client hmset Table1 Id 9324325 Re
  • 如何在实时添加对象时从 Redis 中弹出对象?

    我想让 Node js 进程运行 因为它正在检查 Redis 服务器是否有任何新的弹出内容 另一个进程将偶尔进行推送 而 Node 进程将尝试弹出任何进来的内容 Node 进程将保持运行 有人能给我指出一个好的方向吗 我正在尝试找出如何监听
  • AWS Redis 从外部连接

    有没有办法从外部 AWS 网络连接 AWS 上托管的 Redis 实例 我有一个基于 Windows 的 EC2 实例在 AWS 上运行 另一个是 Redis 缓存节点 我知道有人问过这个问题 但答案是在基于 Linux 的系统中 但我的是
  • socket.io redis 和内存泄漏

    我的socket io版本是 电子邮件受保护 cdn cgi l email protection and 电子邮件受保护 cdn cgi l email protection 我在 Windows 上 在某些地方 我看到问题已得到解决 我
  • 使用brew在MacOSx上安装Redis JSON

    如何使用brew 在 macOSx 上安装 RedisJSON 如何在不编译redis的情况下启用redis上的模块 我不想使用 docker 客户端 Redis Stack 可能是最简单的方法 它不仅仅是 RedisJSON 还包括 Re
  • 如何从 python 将无穷大传递给 redis?

    我正在使用 redis py 并希望将 inf 和 inf 与 ZRANGEBYSCORE 一起使用 我尝试使用 inf 的字符串和浮点来执行此操作 但它们返回一个空集 我怎样才能做到这一点 EDIT 我尝试执行以下命令 redis Str
  • connect-redis - 如何保护会话对象免受竞争条件影响

    我使用 nodejs 和 connect redis 来存储会话数据 我将用户数据保存在会话中 并在会话生命周期中使用它 我注意到两个更改会话数据的请求之间可能存在竞争条件 我尝试过使用 redis lock 来锁定会话 但这对我来说有点问
  • 仅当尚未设置时才进行原子设置

    仅当尚未在 Redis 中设置时 是否有办法执行原子设置 具体来说 我正在创建一个像 myapp user user email 这样的用户 并且希望 Redis 在 user email 已被占用时返回错误 而不是默默地替换旧值 比如声明
  • 如何设置 Celery 以通过 ssl 与 Azure Redis 实例对话

    使用 的伟大答案 如何在microsoft azure上的django项目中配置celery redis https stackoverflow com questions 39616701 how to configure celery
  • 库存管理系统的 SQL 与 NoSQL

    我正在开发一个基于 JAVA 的网络应用程序 主要目的是拥有在多个称为渠道的网站上销售的产品的库存 我们将担任所有这些渠道的管理者 我们需要的是 用于管理每个渠道的库存更新的队列 库存表 其中包含每个通道上分配的正确快照 将会话 ID 和其
  • Docker-compose Predis 不通过 PHP 连接

    我正在尝试使用 docker compose 将 PHP 与 redis 连接 docker compose yml version 2 services redis image redis 3 2 2 php image company
  • redis-cli 重定向到 127.0.0.1

    我在PC1上启动Redis集群 然后在PC2上连接它 当需要重定向到另一个集群节点时 它会显示Redirected to slot 7785 located at 127 0 0 1 但应该显示Redirected to slot 7785
  • Redis INCRBY 有限制

    我想知道是否有一种方法可以通过我的应用程序的单次往返在 Redis 中执行此操作 对于给定的键K 其可能值V是范围内的任意整数 A B 基本上 它有上限和下限 When an INCRBY or DECRBY发出命令 例如INCRBY ke
  • 如何批量删除Redis中数十万个带有特殊字符的key

    我们有一个包含数十万个 Redis 键的列表 其中包含各种特殊字符 我们希望批量删除它们 对于这个问题上的类似问题 有一些很好的答案 如何使用 Redis 自动删除与模式匹配的键 https stackoverflow com questi
  • 在 Kubernetes/Openshift 中将客户端-服务器流量保持在同一区域的最佳方法?

    我们运行兼容 Kubernetes OKD 3 11 的本地 私有云集群 其中后端应用程序与用作缓存和 K V 存储的低延迟 Redis 数据库进行通信 新的架构设计将在两个地理上分布的数据中心 区域 之间平均划分工作节点 我们可以假设节点
  • Redis SYNC 套接字上的错误情况:连接被拒绝

    在我的 django 应用程序中使用 celery 和 redis 一切都工作正常 直到我遇到了问题 redis 文件的位置已更改 redis 无法访问它们 经过查找 原来这是由于网络随机攻击造成的 需要添加confg 我添加文件后 一段时
  • Laravel 所有会话 ID 与 Redis 驱动程序

    在我的应用程序中 我希望允许某些用户能够注销除他 她之外的所有其他用户 当会话驱动程序设置为文件时 我已经完成了此功能 但现在我使用 redis 作为会话驱动程序 并且我无法找到任何方法来列出所有当前会话 就像我在文件时所做的那样司机 问题
  • redis - 使用哈希

    我正在使用 redis 为我的 Web 应用程序实现社交流和通知系统 我是 redis 的新手 我对哈希值及其效率有一些疑问 我读过这篇很棒的文章Instagram 帖子 http instagram engineering tumblr

随机推荐

  • CDN是如何实现网络加速的?

    最近很多网站用户都在谈论香港服务器的同时 也在讨论CDN加速服务的相关话题 谈论的目的就是想通过相关的设置和服 务来有一个好的上网体验 同时减少同行DDOS的攻击 那么 对网站进行CDN加速服务到底能够让网络实现哪些功能呢 第一 能实现全球
  • CDN可以给企业网站带来哪些优势?

    企业网站带来哪些优势 现在企业最关心的问题 就是我的网站能不能打开 用户访问到的是不是正常的页面 网站是否能够正常运营 而互联网是 一个开放式的平台 网站是否能够正常运营和很多因素都有关系 比如服务器 带宽 CPU处理能力等等 而最重要的就
  • Java版 招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计

    项目说明 随着公司的快速发展 企业人员和经营规模不断壮大 公司对内部招采管理的提升提出了更高的要求 在企业里建立一个公平 公开 公正的采购环境 最大限度控制采购成本至关重要 符合国家电子招投标法律法规及相关规范 以及审计监督要求 通过电子化
  • java 版本企业招标投标管理系统源码+多个行业+tbms+及时准确+全程电子化

    项目说明 随着公司的快速发展 企业人员和经营规模不断壮大 公司对内部招采管理的提升提出了更高的要求 在企业里建立一个公平 公开 公正的采购环境 最大限度控制采购成本至关重要 符合国家电子招投标法律法规及相关规范 以及审计监督要求 通过电子化
  • 远程办公模式的流行:以灵活性应对当今工作环境

    随着科技的进步和全球化的发展 远程办公模式正变得越来越流行 本文将探讨远程办公模式的流行趋势 以及它如何为当今不断变化的工作环境带来灵活性和适应性 1 科技的进步 随着互联网 云计算和即时通讯工具的发展 远程办公变得更加便捷和高效 无论身在
  • 揭秘移动电源容量:虚标还是品质问题?

    在购买移动电源时 我们经常会听到关于移动电源容量的一些争议 有人认为移动电源的容量存在虚标 实际容量远远达不到标称值 有人认为移动电源的品质存在问题 转换率低下导致实际充电效果不佳 还有人说使用久了之后 电池会有损耗 导致充电效果打折 那么
  • jdk11启动jdk8 jar包报错

    一 前言 开发使用jdk8版本开发的服务打包后 使用jdk11版本的java启动服务 导致出现以下报错 java lang NoClassDefFoundError javax xml bind DatatypeConverter 二 解决
  • jenkins设置中文

    安装以下两个插件 Locale plugin Localization Chinese Simplified 在jenkins的system配置中找到locale配置项 在locale配置项的默认语言中填入以下内容保存 zh CN 重启je
  • Windows的最大威胁是尽然是“套皮安卓”的鸿蒙系统

    前言 自从鸿蒙问世以来 套皮安卓的言论就没有断过 但是那些现在还在说鸿蒙是套皮安卓的人 你知不知道微软已经组建了专门的 战略团队 来对付鸿蒙 因为这些专业的人早已经知道鸿蒙将是Windows的巨大威胁了 微软作为一个垄断操作系统多年的巨无霸
  • 短视频时代:如何设计吸引人的黄金3秒开头

    在短视频时代 一个好的开头对于视频的点击率和观看率至关重要 黄金3秒 作为短视频开头最关键的时刻 决定了观众是否愿意继续观看你的视频 那么 如何设计一个吸引人的黄金3秒开头呢 下面将为你揭秘抓住观众注意力的秘诀 一 利用好奇心 好奇心是人类
  • 从大厂到高校,鸿蒙人才“红透半边天”

    前言 近两个月来 纯血鸿蒙未发先火 连带让鸿蒙人才的培养和争夺 也红透半边天 最近 华为人才在线官网公示了2023年教育部产学合作协同育人项目华为第二批项目立项 其中 哈尔滨工业大学 天津大学 电子科技大学等16所高校鸿蒙项目立项已通过 这
  • 深入探讨Android启动优化策略

    深入探讨Android启动优化策略 在当今激烈竞争的移动应用市场 应用的启动速度直接影响着用户的第一印象和满意度 作为主流的移动操作系统之一 Android的启动优化是开发者必须关注的关键领域 本文将详细介绍一些强大有效的Android启动
  • Java 17 & Java 11:新功能探索与改进措施知多少?

    7是Java编程语言的最新 LTS 长期支持 版本 于 2021年9月14日发布 如果您目前使用的是Java11 那么也许是时候考虑迁移到 Java 17啦 方便我们体验新功能以及了解新版本的改善措施 在本文中 我们将讨论 Java 17
  • 鸿蒙开发入门:应用配置文件概述(FA模型)

    应用配置文件概述 FA模型 每个应用项目必须在项目的代码目录下加入配置文件 这些配置文件会向HarmonyOS的编译工具 HarmonyOS操作系统和应用市场提供描述应用的基本信息 应用配置文件需申明以下内容 应用的软件包名称 应用的开发厂
  • 从面试官角度看Handler:掌握技巧,事半功倍!

    引言 在Android开发领域 Handler是一项关键技能 尤其在面试中 对Handler的深刻理解和熟练运用往往是衡量一位Android开发者水平的重要标志 本文将从面试官的角度出发 针对Android Handler技术展开详细的解析
  • 鸿蒙程序员突然走俏招聘市场,大厂为什么要争相鸿蒙高手?

    前言 近期 一股奇特的暖流席卷了国内的IT就业市场 如果你浏览一下各大招聘网站 你会发现一个令人惊讶的现象 鸿蒙程序员的招聘需求激增 众多大厂纷纷抛出橄榄枝 竞相争夺这些稀缺的人才 一时间 鸿蒙程序员成为了招聘市场的香饽饽 各大公司似乎都在
  • 鸿蒙开发一员难求,你知道现在鸿蒙工程师这个岗位有多火热吗?

    前言 你知道现在鸿蒙工程师这个岗位有多火热吗 只要有一年开发经验 我所在的公司都能开到35K的月薪 这本来是至少5年以上开发经验 还得有成功项目经验的 主程 才有的待遇 关键是这样了 还找不上人 本来有一个都答应入职了 第二天就要办手续 人
  • 机器学习的12个基础问题

    1 阐述批归一化的意义 算法 1 批归一化变换 在一个 mini batch 上应用于激活 x 批归一化是一种用于训练神经网络模型的有效方法 这种方法的目标是对特征进行归一化处理 使每层网络的输出都经过激活 得到标准差为 1 的零均值状态
  • 如何应对Android面试官->CAS基本原理

    基本原理 CAS基本原理 Compare And Swap 利用了现代处理器都支持 CAS 指令 循环这个指令 直到成功为止 什么是原子操作 如何实现原子操作 原子操作 要么全部完成 要么全部都不完成的操作 例如 synchronized
  • 人为制造redis的热key、大key引发的线上事故

    背景 Redis中间件 我们主要是用来做缓存 缓解数据库的访问压力 我们搭建的是redis集群 在一个风和日丽的下午 突然收到运维的报警信息 运维 小李 你们使用的redis中间件所在的服务器 有大量的流量流出 宽带快要占满了 网卡都冒烟了