Redis 大Key排查与优化

news2024/9/28 3:20:44

Redis 大Key排查与优化

什么是BigKey

bigkey简单来说就是存储本身的key值空间太大,或者hash,list,set等存储中value值过多。没有具体的衡量标准。

参考的大小范围:

  • String 类型值大于10KB。
  • Hash、List、Set、Zset类型元素个数超过5000个。

创建Bigkey

vim /etc/redis/redis.conf

# 不做任何的清理工作,在redis的内存超过限制之后,所有的写入操作都会返回错误;但是读操作都能正常的进行
maxmemory-policy noeviction

然后可以使用redis-cli 获取通过代码设置超过阈值的key,从而就会产生大key了。

排查Redis大key的方法

redis-cli --bigkeys

特点:

  • 使用–bigkeys参数会扫描整个Redis数据库,应该在低流量峰值时执行

  • 这个方法只能返回每种类型中最大的那个bigkey,无法得到大小排到前N位的bigkey

  • 对于集合类型来说,这个方法只统计集合元素的多少,而不是实际占用的内存量。因为一个集合中元素个数多,并不一定占用内存就多


    @GetMapping("init")
    @Async
    public void initData(@RequestParam (name = "size", defaultValue = "5000") Integer size){

        redisTemplate.opsForValue().set("string_large_key1", generateTestData(10* 1024));
        redisTemplate.opsForValue().set("string_large_key2", generateTestData(10* 1024));

        redisTemplate.opsForSet().add("set_large_key1", new HashSet<>(50000));
        redisTemplate.opsForSet().add("set_large_key2", new HashSet<>(50000));

        redisTemplate.opsForHash().putAll("hash_large_key1", buildMapData(50000));
        redisTemplate.opsForHash().putAll("hash_large_key2", buildMapData(50000));

        redisTemplate.opsForList().rightPushAll("list_large_key1", buildListData(50000));
        redisTemplate.opsForList().rightPushAll("list_large_key2", buildListData(50000));
    }



    private Map buildMapData(int initialCapacity){

        Map<String, String> result =new HashMap<>(initialCapacity);
        for (int i = 0; i < initialCapacity; i++) {
            result.put("kevin_" + i, "123");
        }
        return result;

    }

    private List<String> buildListData(int initialCapacity){
        List<String> result = new ArrayList<>(initialCapacity);
        for (int i = 0; i < initialCapacity; i++) {
            result.add("kevin_" + i );
        }
        return result;

    }

  • 使用–bigkeys查询
root@DESKTOP-0JS7U4E:~# redis-cli -h 127.0.0.1 -p 16379 --bigkeys

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest hash   found so far 'hash_large_key2' with 50000 fields

# 只返回了最大的那个bigkey
[00.00%] Biggest string found so far 'string_large_key2' with 10485762 bytes
[00.00%] Biggest set    found so far 'set_large_key2' with 1 members
[00.00%] Biggest list   found so far 'list_large_key1' with 50000 items

-------- summary -------

Sampled 9 keys in the keyspace!
Total key length in bytes is 135 (avg len 15.00)

Biggest   list found 'list_large_key1' has 50000 items
Biggest   hash found 'hash_large_key2' has 50000 fields
Biggest string found 'string_large_key2' has 10485762 bytes
Biggest    set found 'set_large_key2' has 1 members

# 返回了list的容量
2 lists with 100000 items (22.22% of keys, avg size 50000.00)
# 返回了hash的容量
2 hashs with 100000 fields (22.22% of keys, avg size 50000.00)
2 strings with 20971524 bytes (22.22% of keys, avg size 10485762.00)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
3 sets with 3 members (33.33% of keys, avg size 1.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
root@DESKTOP-0JS7U4E:~#

redis-cli scan VS memory usage组合

实际上bigkey的底层也使用SCAN命令执行。

SCAN命令可以用于迭代遍历所有key。它是一个非阻塞操作,支持游标(cursor)的方式来逐步遍历所有key。使用SCAN命令可以避免阻塞,减少对Redis性能的影响。

Redis Scan命令说明

1、先使用scan扫描出key

127.0.0.1:16379> scan 1000 MATCH "string*"
1) "0"
2) 1) "string_large_key2"
   2) "string_large_key1"
127.0.0.1:16379>
127.0.0.1:16379> scan 0 MATCH "string*" count 20
1) "0"
2) 1) "string_large_key2"
   2) "string_large_key1"
127.0.0.1:16379>


2、使用 memory usage查询key占用的内存大小

127.0.0.1:16379> memory usage string_large_key1
(integer) 10485831
127.0.0.1:16379>

这样组合的方式操作比较复杂,需要对命令使用非常熟悉。在生产环境需要更快,更高效的发现问题还是建议使用成熟的分析工具,毕竟也都是用这些命令组合起来的。

使用云上的Redis可以直接使用CloundDBA功能

redis-rdb-tools

该三方工具Github地址redis-rdb-tools。

安装该分析工具

python setup.py install

要使用memory功能,需要安装

pip3 install python-lzf

如果出现没有权限的问题,那就以管理员打开cmd再运行

error: [Errno 13] Permission denied: 'C:\\Python310\\Scripts\\rdb-script.py'

安装完成之后目录下面多出这几个文件。

C:\Python310\Scripts>dir
....................
2024/08/08  13:38               996 rdb-script.py
2024/08/08  13:38            74,752 rdb.exe
2024/08/08  13:38             1,030 redis-memory-for-key-script.py
2024/08/08  13:38            74,752 redis-memory-for-key.exe
2024/08/08  13:38             1,018 redis-profiler-script.py
2024/08/08  13:38            74,752 redis-profiler.exe

C:\Python310\Scripts>

使用rdb进行分析

C:\Python310\Scripts>rdb --command memory --bytes 102400 \\wsl.localhost\Ubuntu-20.04\var\lib\redis\dump.rdb
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry
0,hash,hash_large_key2,3186588,hashtable,50000,11,
0,hash,hash_large_key1,3186588,hashtable,50000,11,
0,string,string_large_key1,12582976,string,10485762,10485762,
0,list,list_large_key1,744355,quicklist,50000,13,
0,string,string_large_key2,12582976,string,10485762,10485762,
0,list,list_large_key2,744355,quicklist,50000,13,

C:\Python310\Scripts>

也可以加上-f参数,将结果输出到本地文件中。

rdb --command memory --bytes 102400 \\wsl.localhost\Ubuntu-20.04\var\lib\redis\dump.rdb -f d:\kevin.csv

大key问题如何优化

不管使用那种方式优化该问题,中心思想还是要体现在“预防大于后置处理”。在设计之初就要考虑是否会随着时间推移慢慢的出现大key的问题,从而融入优化解决的策略进去。

压缩数据

对于大量重复的数据,可以对数据压缩存储,减少存储空间。Redis提供了一些压缩算法,比如LZF,Snappy等,可以在存储和读取的时候进行压缩、解压操作。

数据拆分

也可以理解成,优化数据结构。

  • string类型
    • 存储关键数据,剔除非关键数据
    • 对于已经出现的大key,可以将其拆分成多个小型key
    • 大对象分拆成几个key-value,每个field代表一个具体的属性,使用hget,hmget来获取部分的value,使用hset,hmset来更新部分属性
  • 集合类型
    • 业务允许前提下,可以将集合类型拆分成多个string类型,同时统一前缀,通过mget和mset来访问。

建立Redis key 和value的规范

建立相关的开发规范和运维流程,比如限制单个string类型key的大小,集合类型的容量大小。在设计阶段就一定程度上面规避掉该风险。

合理的过期时间配置

对于不需要长期保存的数据,可以设置较短的过期时间,避免数据长期占用Redis服务器的内存资源,导致大key问题的发生

定期监控

通过 Redis 的监控工具、日志和性能分析工具来进行监控和优化。及时的发现问题,在没有产生大故障之前就消灭在摇篮里面。

增加Redis资源

硬件资源的扩展对软件层面的优化,那就是降维打击。

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

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

相关文章

【Mybatis Plus】Mybatis Plus_快速上手

文章目录 1.Mybatis Plus 简介2.与SpringBoot集成2.1在maven中引入MP依赖2.3 在application.yml中&#xff0c;配置好自己的数据库文件 3. 快速上手 创建实体类entity/User.java3.1创建通用Mapper3.2 使用继承了BaseMapper的Mapper开始编写Crud3.2.1 Insert3.2.2 deleted3.2.3 …

5.1树的基本概念

5.11树的定义 树是n>0的有限集.树适用于有层次结构的数据 只有根节点无前驱 只有叶子节点无后继 有后继的节点为分支节点 除根节点外,任何一个节点都有且只有一个前驱 5.12树的基本术语 祖先节点:从k-->R经过的所有节点 子孙节点:从一个节点出发后下面的所有节点 …

Oracle【plsql编写九九乘法表】

九九乘法表 DECLAREi NUMBER : 1;j NUMBER : 1; BEGINFOR i IN 1 .. 9LOOPFOR j IN 1 .. iLOOPDBMS_OUTPUT.put (i || * || j || || i * j || );END LOOP;DBMS_OUTPUT.put_line ( );END LOOP; END;输出结果

【YashanDB数据库】Ubuntu系统加载Yashan C驱动后无法使用PHP

【问题分类】驱动使用 【关键字】驱动使用、PHP、Ubuntu、C驱动 【问题描述】 客户将YashanDB的C驱动lib加载到环境变量LD_LIBRARY_PATH后&#xff0c;PHP报错&#xff1a;PHP Fatal error&#xff1a;Unable to start pcre module in Unknown on line 0 【问题原因分析】经…

集成学习:融合多个模型

集成学习 是一种机器学习范式&#xff0c;它创建一组模型&#xff0c;并将它们的预测结果结合起来&#xff0c;以期望最终模型能够优于单个模型。集成学习的关键在于如何有效地结合不同的模型。 集成学习算法分为&#xff1a;Bagging&#xff0c;Boosting和Stacking等类型。 B…

关于k8s集群的存储卷

目录 1.emptyDir存储卷 2.hostPath存储卷 3.nfs共享存储卷 容器磁盘上的文件的生命周期是短暂的&#xff0c;这就使得在容器中运行重要应用时会出现一些问题。首先&#xff0c;当容器崩溃时&#xff0c;kubelet 会重启它&#xff0c;但是容器中的文件将丢失——容器以干净的…

大神器! 直接显示中英文期刊的等级, 及该期刊在中国顶级大学的认可度!

今天&#xff0c;推荐一款学术神器——easyScholar&#xff0c;别看这个插件小小的&#xff0c;它的功能非常强大。 它可以显示期刊的影响因子、中科院分区、JCR分区等信息&#xff01; 比如&#xff0c;它可以在知网数据库中显示期刊等级信息。 也能够在万方数据库中显示期刊等…

【Linux WEB】Linux嵌入式WEB服务器(BOA)部署

1. 下载boa源码 进入官网下载http://www.boa.org/news.html&#xff0c;版本为0.94.13 2. 交叉编译boa源码 2.1 解压boa源码压缩包   将下载好的压缩包放入到Ubuntu系统中进行解压 tar -zxvf boa-0.94.13.tar.gz 2.2 生成并配置Makefile文件 &#xff08;1&#xff09;将…

交换机常用的贴片网络变压器,滤波器H5084NL / H82409S

华强盛电子导读千兆交换机&#xff1a; 199/2643/0038 在交换机行业中&#xff0c;常用的贴片网络变压器和滤波器型号会根据具体的应用需求、性能指标、成本考量等因素而有所不同。通常&#xff0c;这些器件需要满足网络通信中的高频传输、阻抗匹配、信号隔离、电磁兼容&…

【C++】vector 的模拟实现

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

⌈ 传知代码 ⌋ CNN实现脑电信号的情感识别

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

怎么压缩ppt文件?4个常用的PPT压缩技巧分享!

在当今数字化的工作和学习环境中&#xff0c;PPT已经成为我们表达观点、展示成果的重要工具。然而&#xff0c;有时PPT文件的体积过大&#xff0c;给我们的分享和存储带来了诸多不便&#xff0c;表现在&#xff1a;无端占用宝贵的磁盘空间&#xff0c;接收下载耗费时间长等。 …

KSV1(KSU1)/KSV5(KSU5)-创建分配(分摊)规则/运行分配

将A成本中心费用分摊给B、C两个成本中心&#xff1a; 将B、C两个成本中心建一个成本中心组KSV1-创建分配规则 选择发送方的成本中心&#xff0c;选择接收方的成本中心 给不同成本中心分配比例。 点击保存 点击概览可以看到该条规则&#xff0c;可以在系统中创建多条规则。 K…

优阅达携手 HubSpot 助力出海企业营销、销售和服务自动化

2024 年 6 月 17 - 18 日&#xff0c;GTC 2024 全球流量大会在深圳福田会展中心圆满举办。作为跨境出海行业产业链最全、资源最丰富、规模最大的专业展会之一&#xff0c;本次大会聚集了近 3 万名从业者、超过 200 家海内外优质开发厂商&#xff0c;品牌方、服务商&#xff0c;…

【海贼王航海日志:前端技术探索】CSS你了解多少?(二)

目录 1 -> 字体属性 1.1 -> 设置字体 1.2 -> 字体大小 1.3 -> 字体粗细 1.4 -> 文字样式 2 -> 文本属性 2.1 -> 文本颜色 2.1.1 -> 认识RGB 2.1.2 -> 设置文本颜色 2.2 -> 文本对齐 2.3 -> 文本装饰 2.4 -> 文本缩进 2.5 -&g…

Go开发后端和Vue3开发前端的前后端分离框架中自己手戳一个OA流程审批、工作流引擎给新时代一个漂亮便捷的工作流引擎

前言 在软件项目开发中&#xff0c;我们都会接触到流程审批的需要业务&#xff0c;我们以往用的最多就是如下图这种流程编辑引擎插件&#xff1a; 以上截图中的流程工具是不是大家常见的呀&#xff01;感觉很丑拿不出手呀&#xff01;在当前行业内卷及竞争激烈情况下&#xff…

uniapp免费申请苹果证书教程每次7天可用于测试

准备一个苹果账号没有加入过任何组织的 然后下载appuploader下载链接 登录上去切记勾选上未付苹果688 然后点击苹果证书创建p12证书 创建描述文件 uniapp打包自定义基座 这就打包好了可以愉快地开发了&#xff0c;但每次生成只有7天&#xff0c;设备限制3个&#xff0c…

【C++】STL | priority_queue 堆(优先级队列)详解(使用+底层实现)、仿函数的引入、容器适配器的使用

目录 前言 总代码 堆的简介 仿函数 堆的基础框架建立size、empty、top、 向上调整法 and push 向上调整 push 向下调整法 and pop 向下调整法 pop 迭代器区间初始化&#xff08;构造&#xff09; 逻辑讲解 为何选择向下建堆&#xff1f; 建堆代码实现 结语 前言…

区块链的搭建和运维4

区块链的搭建和运维4 (1) 搭建基于MySQL分布式存储的区块链 1.构建单群组网络节点 使用开发部署工具构建单群组网络节点&#xff0c;命令如下&#xff1a; bash build_chain.sh -l 127.0.0.1:4 -p 30300,20200,85452. 启动 MySQL 并设置账户密码 输入如下命令&#xff0c;…

【mysql 第一篇章】系统和数据库的交互方法

一、宏观的查看系统怎么和数据库交互 在我们刚刚接触系统和数据库的时候不明白其中的原理&#xff0c;只知道系统和数据库是需要交互的。所以我们会理解成上图的形式。 二、MYSQL 驱动 随着我们的学习时间的加长以及对程序的了解&#xff0c;发现链接数据库是需要有别的工具辅…