Redis--21--大Key问题解决方案

news2025/1/16 22:48:56

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
        • Redis--20--大Key问题解析
  • 一、如何发现Redis大Key
    • 1. 使用Redis命令行工具
      • **MEMORY USAGE**
      • **RANDOMKEY**
      • **DEBUG OBJECT**
      • **SCAN命令**
      • **redis-cli 工具:**
    • 2. 使用监控工具
      • 2.1 Redis自带的慢查询日志
      • 2.2 第三方监控平台
      • 2.3 专用大Key扫描工具
    • 3. 定期巡检和自动化告警
  • 二、如何解决大key问题
    • 1.删除大key
      • 异步UNLINK命令
      • SCAN命令
    • 2.压缩和拆分key (不可删除数据)
    • 1.压缩算法、
      • 使用 Redis 的数据结构
    • 2.拆分大 Key
    • 3.分片
  • 三、实际案例分析
    • 案例1:线上服务因大Key删除导致卡顿
    • 案例2:数据迁移中的大Key问题
    • 案例3:社交媒体应用中的大列表
    • 案例4:电商平台中的大哈希表
    • 案例5:日志系统中的大集合
  • 四、经验总结和最佳实践
    • 1. 日常监控和巡检
    • 2. 合理的容量规划
    • 3. Redis使用的常见陷阱及规避方法
    • 4. 工具和脚本的高效利用
    • 5. 团队协作和优化文化


前言

Redis–20–大Key问题解析

一、如何发现Redis大Key

在排查Redis性能问题时,发现和定位大Key是解决问题的关键步骤。以下是一些常用的方法和工具,可以帮助识别和诊断Redis中的大Key。

1. 使用Redis命令行工具

Redis 提供了一些工具和命令来识别大 Key:

MEMORY USAGE

  • 作用:返回指定Key的内存占用大小(以字节为单位)。
示例:
MEMORY USAGE mykey
  • 输出结果会显示该Key的大小,通过与其他Key对比,可以发现异常占用内存的大Key。

RANDOMKEY

  • 作用:随机返回一个Key,用于抽样分析。
示例:
RANDOMKEY
  • 配合MEMORY USAGE或DEBUG OBJECT命令,可以抽样检查Key的大小和属性。

DEBUG OBJECT

  • 作用:提供关于Key的详细调试信息,包括编码方式和元素个数。
示例:
DEBUG OBJECT mykey
  • 输出信息中的serializedlength字段可作为判断Key大小的重要依据。

SCAN命令

  • 作用:增量遍历Redis中的Key,适合在大数据量环境下使用。
示例:
SCAN 0 MATCH * COUNT 100
  • 遍历过程中结合MEMORY USAGE或其他分析工具,可以识别出大Key。

redis-cli 工具:

  • 作用:可以使用 redis-cli 命令来查找和分析大 Key。
示例:
redis-cli --bigkeys

2. 使用监控工具

2.1 Redis自带的慢查询日志

  • 配置SLOWLOG参数,记录执行时间较长的命令。
示例:
SLOWLOG GET 10
  • 通过分析慢查询日志,可以定位哪些操作耗时过长,并进一步确认是否因大Key导致。

2.2 第三方监控平台

  • Prometheus + Grafana:通过Redis Exporter收集监控数据,设置内存占用、命令执行时间等指标的报警规则。
  • Datadog:可视化展示Redis实例的性能数据,包括每个Key的内存占用。
  • 阿里云、腾讯云等云监控工具:对Redis实例进行实时分析,快速定位异常Key。

2.3 专用大Key扫描工具

  • 开源工具如redis-rdb-tools:通过分析RDB文件识别大Key。
  • 在线扫描工具:通过API或脚本对Key逐个检查,生成大Key列表。

3. 定期巡检和自动化告警

  • 定期巡检脚本
    • 定时运行扫描脚本,生成大Key报告。
    • 将结果输出到日志或发送邮件告警。
  • 设置监控阈值
    • 配置Redis监控指标,如单个Key的最大内存占用。
    • 通过自动化告警(如邮件、短信、钉钉机器人)及时通知异常。

在这里插入图片描述

二、如何解决大key问题

  • 根据大key的实际用途可以分为两种情况:可删除和不可删除。

在这里插入图片描述

1.删除大key

如果发现某些大key并非热key就可以在DB中查询使用,则可以在Redis中删掉:

异步UNLINK命令

当Redis版本大于4.0时,可使用UNLINK命令安全地删除大Key,该命令能够以非阻塞,异步执行的方式,逐步地清理传入的Key。

  • Redis UNLINK 命令类似与 DEL 命令,表示删除指定的 key,如果指定 key 不存在,命令则忽略。
  • UNLINK 命令不同与 DEL 命令在于它是异步执行的,因此它不会阻塞。
  • UNLINK 命令是非阻塞删除,非阻塞删除简言之,就是将删除操作放到另外一个线程去处理。
UNLINK mykey

SCAN命令

当Redis版本小于4.0时,避免使用阻塞式命令KEYS,而是建议通过SCAN命令执行增量迭代扫描key,然后判断进行删除。
在这里插入图片描述

2.压缩和拆分key (不可删除数据)

  • 当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。
  • 当value是string,压缩之后仍然是大key,则需要进行拆分,一个大key分为不同的部分,记录每个部分的key,使用multiget等操作实现事务读取。
  • 当value是list/set等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。

1.压缩算法、

  • 当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。

使用 Redis 的数据结构

根据数据的特性选择合适的 Redis 数据结构。Redis 提供了多种数据结构(如列表、集合、有序集合、哈希表),可以根据实际需求选择合适的数据结构来优化存储和访问性能。

示例:使用哈希表优化存储

  • 替代长列表或大字符串:

HSET user🔢name “John” user🔢age “30”

2.拆分大 Key

  • 将大 Key 拆分为多个小 Key 是一种常见的优化策略。例如,将一个大的列表拆分为多个小列表,或者将一个大的哈希表拆分为多个小哈希表。这样可以减少单个操作对性能的影响。
// 原始大哈希表
HSET largeHash key1 value1
HSET largeHash key2 value2
...
 
// 拆分为多个小哈希表
HSET smallHash1 key1 value1
HSET smallHash2 key2 value2
...

3.分片

  1. 如果一个List或Set数据量过大,可以通过分片技术将其拆分成多个Key:
  2. 按照业务逻辑对数据进行分片,将其拆分为多个Key,并进行并行操作。

示例:存储用户订单数据时,可以按照用户ID进行分片。

list:0, list:1, list:2 …

三、实际案例分析

案例1:线上服务因大Key删除导致卡顿

在这里插入图片描述
在这里插入图片描述

案例2:数据迁移中的大Key问题

在这里插入图片描述
在这里插入图片描述

案例3:社交媒体应用中的大列表

在这里插入图片描述
解决方案:

  1. 拆分好友列表:将每个用户的好友列表拆分为多个小列表,例如按字母顺序或好友的加入时间进行分组。
// 将一个大的好友列表拆分为多个小列表
String userId = "user:12345";
String[] friends = getFriends(userId);
for (int i = 0; i < friends.length; i += 1000) {
    String smallListKey = userId + ":friends:" + (i / 1000);
    List<String> smallList = Arrays.asList(Arrays.copyOfRange(friends, i, Math.min(i + 1000, friends.length)));
    redisClient.rpush(smallListKey, smallList.toArray(new String[0]));
}
  1. 优化查询:在查询好友列表时,根据实际需要选择查询具体的小列表而不是整个大列表。

案例4:电商平台中的大哈希表

在这里插入图片描述

解决方案:

  1. 拆分大哈希表:将每个产品的哈希表拆分为多个小哈希表,按照不同的信息类型进行分组。例如,将库存和价格信息分开存储。
// 拆分大哈希表
String productId = "product:12345";
Map<String, String> productDetails = getProductDetails(productId);
 
// 存储库存信息
redisClient.hset(productId + ":stock", productDetails.get("stock_key"), productDetails.get("stock_value"));
 
// 存储价格信息
redisClient.hset(productId + ":price", productDetails.get("price_key"), productDetails.get("price_value"));
  1. 定期压缩:定期压缩和优化哈希表的数据结构,删除不再需要的信息,以减少存储和操作的复杂性。

案例5:日志系统中的大集合

在这里插入图片描述

四、经验总结和最佳实践

在实际生产环境中,合理应对Redis大Key问题需要结合预防、监控和优化的多种手段。以下是一些经验总结和最佳实践,帮助开发和运维团队更高效地管理Redis系统。

1. 日常监控和巡检

在这里插入图片描述

2. 合理的容量规划

在这里插入图片描述

3. Redis使用的常见陷阱及规避方法

在这里插入图片描述

4. 工具和脚本的高效利用

在这里插入图片描述

5. 团队协作和优化文化

在这里插入图片描述

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

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

相关文章

微信小程序订阅消息提醒-云函数

微信小程序消息订阅分2种&#xff1a; 1.一次性订阅&#xff1a;用户订阅一次就可以推送一次&#xff0c;如果需要多次提醒需要多次订阅。 2.长期订阅&#xff1a;只有公共服务领域&#xff0c;如政务、医疗、交通、金融和教育等。‌在用户订阅后&#xff0c;在很长一段时间内…

Ubuntu上,ffmpeg如何使用cuda硬件解码、编码、转码加速

本文使用 Ubuntu 环境。Ubuntu 直接使用 APT 安装的就支持 CUDA 加速。本文使用这样下载的版本进行演示&#xff0c;你自己编译或者其他源的版本可能会不同。 ffmpeg 的一些介绍&#xff0c;以及 macOS 版本的 ffmpeg 硬件加速请见《macOS上如何安装&#xff08;不需要编译安装…

了解Python中的SciPy库

么是 SciPy&#xff1f; SciPy&#xff08;发音为“Sigh Pie”&#xff09;是 Scientific Python 的首字母缩写词&#xff0c;它是 Python 的开源库&#xff0c;用于科学和技术计算。它是 Python 编程语言中称为 Numpy 的基本数组处理库的扩展&#xff0c;旨在支持高级科学和工…

51单片机入门基础

目录 一、基础知识储备 &#xff08;一&#xff09;了解51单片机的基本概念 &#xff08;二&#xff09;掌握数字电路基础 &#xff08;三&#xff09;学习C语言编程基础 二、开发环境搭建 &#xff08;一&#xff09;硬件准备 &#xff08;二&#xff09;软件准备 三、…

【Qt】01-了解QT

踏入QT的殿堂之路 前言一、创建工程文件1.1 步骤介绍1.2 编译介绍方法1、方法2、编译成功 二、了解框架2.1 main.cpp2.2 .Pro文件2.2.1 注释需要打井号。2.2.2 F1带你进入帮助模式2.2.3 build文件 2.3 构造函数 三、编写工程3.1 main代码3.2 结果展示 四、指定父对象4.1 main代…

【Uniapp-Vue3】使用defineExpose暴露子组件的属性及方法

如果我们想要让父组件访问到子组件中的变量和方法&#xff0c;就需要使用defineExpose暴露&#xff1a; defineExpose({ 变量 }) 子组件配置 父组件配置 父组件要通过onMounted获取到子组件的DOM 传递多个属性和方法 子组件 父组件

qml XmlListModel详解

1、概述 XmlListModel是QtQuick用于从XML数据创建只读模型的组件。它可以作为各种view元素的数据源&#xff0c;比如ListView、GridView、PathView等&#xff1b;也可以作为其他和model交互的元素的数据源。通过XmlRole定义角色&#xff0c;如name、age和height&#xff0c;并…

登录系统网址作业

目录 主页代码 主页​编辑 效果1 登录页面代码 登录页面 效果2 注册页面代码 注册页面 效果3 主页代码 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content&qu…

生产管理看板助力节能科技公司实现数据自动化管理

在节能科技公司的生产过程中&#xff0c;数据管理的自动化是提高生产效率和产品质量的关键。然而&#xff0c;许多公司在数据记录、展示、对比和存档方面仍面临诸多痛点&#xff0c;如产品检测数据无法自动记录、缺乏直观的产线状态展示、检测数据对比繁琐耗时&#xff0c;以及…

论文阅读:Searching for Fast Demosaicking Algorithms

今天介绍一篇有关去马赛克的工作&#xff0c;去马赛克是 ISP 流程里面非常重要的一个模块&#xff0c;可以说是将多姿多彩的大千世界进行色彩还原的重要一步。这篇工作探索的是如何从各种各样的去马赛克算法中&#xff0c;选择最佳的一种。 Abstract 本文提出了一种方法&…

nginx 修改内置 404 页面、点击劫持攻击。

1、在部署前端项目的目录下增加 404.html 页面&#xff1a;/opt/web/404.html。 2、在 nginx 配置中增加 404 配置&#xff1a; root /opt/web; # 设置根目录的配置error_page 404 404.html; location /404.html {root /opt/web;# 指定 404 页面所在的根目录internal;# 确保…

金融项目实战 04|JMeter实现自动化脚本接口测试及持续集成

目录 一、⾃动化测试理论 二、自动化脚本 1、添加断言 1️⃣注册、登录 2️⃣认证、充值、开户、投资 2、可重复执行&#xff1a;清除测试数据脚本按指定顺序执行 1️⃣如何可以做到可重复执⾏&#xff1f; 2️⃣清除测试数据&#xff1a;连接数据库setup线程组 ①明确…

【SH】Xiaomi9刷Windows10系统研发记录 、手机刷Windows系统教程、小米9重装win10系统

文章目录 参考资料云盘资料软硬件环境手机解锁刷机驱动绑定账号和设备解锁手机 Mindows工具箱安装工具箱和修复下载下载安卓和woa资源包第三方Recovery 一键安装Windows准备工作创建分区安装系统 效果展示Windows和Android一键互换Win切换安卓安卓切换Win 删除分区 参考资料 解…

3 前端(上): Web开发相关概念 、HTML语法、CSS语法

文章目录 前言:导学1 Web开发相关概念2 Web标准(网页标准)3 软件架构(CS/BS)(1)C/S: Client/Server 客户端 / 服务器端(2)B/S: Browser/Server 浏览器 / 服务器端VSCode配置前段开发环境一、HTML概念1 概念2 HTML快速入门(1)语法快速入门(2)VSCode一个 !(快捷键…

Docker PG流复制搭建实操

目录标题 制作镜像1. 删除旧的容器2. 创建并配置容器3. 初始化数据库并启动 主库配置参数4. 配置主库5. 修改 postgresql.conf 配置 备库配置参数6. 创建并配置备库容器7. 初始化备库 流复制8. 配置&检查主库复制状态9. 检查备库配置 优化建议问题1&#xff1a;FATAL: usin…

【AIGC】SYNCAMMASTER:多视角多像机的视频生成

标题&#xff1a;SYNCAMMASTER: SYNCHRONIZING MULTI-CAMERA VIDEO GENERATION FROM DIVERSE VIEWPOINTS 主页&#xff1a;https://jianhongbai.github.io/SynCamMaster/ 代码&#xff1a;https://github.com/KwaiVGI/SynCamMaster 文章目录 摘要一、引言二、使用步骤2.1 TextT…

C++类与对象(一)—学习记录

序言&#xff1a;要想开发一款成功的应用程序&#xff0c;其开发者必须充分了解并实现用户的需求。作为一个设计良好的类&#xff0c;既要有直观且易于使用的接口&#xff0c;也必须具备高效的实现过程。 一、类与对象基本概念 面向对象程序设计的主要特点为抽象、封装、继承与…

【React】新建React项目

目录 create-react-app基础运用React核心依赖React 核心思想&#xff1a;数据驱动React 采用 MVC体系package.jsonindex.html好书推荐 官方提供了快速构建React 项目的脚手架&#xff1a; create-react-app &#xff0c;目前使用它安装默认是19版本&#xff0c;我们这里降为18…

Jmeter数据库

jmeter之操作数据库 一、下载jdbc 驱动&#xff0c;安装jdbc驱动 2、将驱动存放在4个路径下 &#xff08;1&#xff09;C:\Program Files\Java\jre1.8.0_60\lib &#xff08;2&#xff09;第二个存放的包 C:\Program Files\Java\jre1.8.0_60\lib\ext &#xff08;3&#xf…

nginx: [emerg] bind() to 0.0.0.0:80 failed 端口被占用

nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions) 查看被占用的端口 被系统占用了 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/HTTP 然后再进入nginx文件夹目录下…