2023-06-21:redis中什么是BigKey?该如何解决?

news2024/9/27 15:22:52

2023-06-21:redis中什么是BigKey?该如何解决?

答案2023-06-21:

什么是bigkey

bigkey是指存储在Key-Value数据库中的键对应的值所占用的内存空间较大。举个例子,如果值是字符串类型,它可以达到最大512MB的存储空间;如果值是列表类型,最多可以存储 2^32 - 1 个元素,即 4294967295 个元素。

根据数据结构的不同,我们可以将bigkey进一步分为字符串类型的bigkey和非字符串类型的bigkey。

字符串类型的bigkey:这种bigkey指的是在Key-Value数据库中,键对应的字符串值所占用的内存空间较大。一般来说,当一个值超过10KB时,就可以被认为是字符串类型的bigkey。但需要注意的是,这个阈值可以根据具体的业务需求和系统的OPS(每秒操作次数)进行调整,不同的环境可能会有不同的定义。

非字符串类型的bigkey:这种bigkey指的是键对应的值是其他非字符串类型(例如哈希、列表、集合、有序集合等),而这些数据结构中的元素数量多到足以被认为是bigkey。例如,当一个哈希表、列表、集合或有序集合中的元素数量超过较大的阈值时,可以被视为非字符串类型的bigkey。

bigkey在Redis中具有不友好的空间复杂度和时间复杂度,以下是它的危害。

bigkey的危害

bigkey的危害体现在三个方面:

1、内存空间不均匀(平衡):特别是在Redis Cluster中,bigkey可能导致节点的内存空间使用不均匀。当某个节点存储了大量的bigkey时,该节点的内存占用会增加,并且可能超出其他节点的内存使用量。这样就破坏了集群的负载均衡,导致一些节点承受了过多的负载,而其他节点却相对空闲。

2、超时阻塞:由于Redis的单线程特性,操作bigkey可能会耗费较长的时间,这也意味着Redis被阻塞的可能性增大。

3、网络拥塞:获取bigkey时产生的网络流量较大,可能引起网络拥塞问题。

假设一个bigkey的大小为1MB,每秒访问量为1000个请求,那么每秒产生的流量将达到1000MB。对于普通的千兆网卡(以字节计算约为128MB/s)的服务器来说,这将带来巨大的网络负载,甚至可能导致灾难性的影响。尤其是在采用单机多实例的方式部署服务器时,一个大型bigkey的影响最终会波及到其他实例上,后果不堪设想。

bigkey的存在并非完全致命:

如果一个bigkey存在但几乎不被频繁访问,那么主要的问题可能是内存空间的不均衡分布,相对于其他问题来说,这个问题的重要性和紧急性可能较低。然而,如果这个bigkey是一个热点key(频繁被访问),那么它所带来的危害就不容忽视。当一个热点bigkey的访问量特别大时,它可能会对Redis服务器和其他实例产生严重的性能影响。

因此,在实际的开发和运维过程中,密切关注bigkey的存在是非常重要的。特别是对于热点bigkey,需要采取相应的策略来应对,例如数据分片、缓存或其他优化措施,以确保系统的高性能和稳定运行。及时监控和处理bigkey问题,有助于维护整体的系统性能和用户体验。

发现bigkey

使用命令redis-cli --bigkeys可以统计和查看bigkey的分布情况。

image.png

在生产环境中,开发和运维人员通常希望能够自定义bigkey的大小,并且找到真正的bigkey,以便能够定位、解决和优化相关问题。

为了判断一个key是否为bigkey,可以执行DEBUG OBJECT key命令并查看serializedlength属性,它表示key对应的value序列化后的字节数。通过检查这个属性,我们可以确定一个key是否为bigkey。

image.png

当需要遍历多个key时,应避免使用keys命令,而是采用SCAN命令来减轻Redis服务器的压力。

scan

自Redis 2.8版本以后,引入了SCAN命令来高效地解决KEYS命令存在的问题。不同于KEYS命令一次性遍历所有键的方式,SCAN采用渐进式遍历的方式,以解决可能引起阻塞的问题。要完全实现KEYS命令的功能,需要执行多次SCAN命令。可以将其想象为逐步扫描字典中的一部分键,直到所有键都遍历完成。

SCAN命令使用方法如下:

SCAN cursor [MATCH pattern] [COUNT number]
  • cursor是必需的参数,实际上是一个游标。第一次遍历时,游标值为0,每次执行完SCAN命令后,会返回当前游标的值,直到游标值为0,表示遍历已结束。

  • MATCH pattern是可选参数,用于指定键名的模式匹配,类似于KEYS命令的模式匹配功能。

  • COUNT number是可选参数,用于指定每次要遍历的键的数量,其默认值为10,如果需要可以适当增大此参数。

image.png

可以观察到,使用SCAN 0命令的第一次执行结果包含两部分:

第一部分是下一次执行SCAN命令所需的游标值(通常是一个整数)。

第二部分是返回的10个键。

接下来可以继续执行SCAN命令,并使用上一次返回的游标值作为参数,直到游标值变为0,表示所有键都已经遍历完毕。

除了SCAN命令,Redis还提供了针对哈希类型、集合类型和有序集合类型的扫描遍历命令,分别是HSCANSSCANZSCAN。它们的作用是解决类似于HGETALLSMEMBERSZRANGE等可能导致阻塞的操作。这些命令的用法类似于SCAN命令,请参考Redis官方文档获取更多信息。

image.png

渐进式遍历确实可以有效解决KEYS命令可能产生的阻塞问题,但并非完美无瑕。在使用SCAN命令进行遍历过程中,如果键空间有变化(增加、删除、修改),可能会遇到以下问题:新增的键可能没有被遍历到,或者遍历结果中可能包含重复的键。因此,在开发过程中需要考虑这些潜在的情况。

当键值个数较多时,使用SCAN命令结合DEBUG OBJECT执行速度可能较慢,此时可以考虑利用Redis的Pipeline机制来提高性能。对于元素个数较多的数据结构,DEBUG OBJECT命令执行速度较慢,并且可能导致Redis阻塞。因此,如果存在从节点,可以考虑在从节点上执行这些操作。

解决bigkey

解决大键(bigkey)的主要思路是拆分,将存储在大键中的数据(大值)进行拆分,分成多个小的值(value1,value2…valueN)进行存储。

例如,如果大值是一个大的JSON对象,可以通过使用MSET命令将该键的内容拆分存储到各个实例中,或者使用哈希表(hash),其中每个字段代表一个具体属性。可以使用HGETHMGET命令来获取部分值,使用HSETHMSET命令来更新部分属性。

同样地,如果大值是一个大的列表(list),可以将其拆分为多个小的列表(list_1,list_2,list_3…list_N)进行存储。

对于其他数据类型也可以采用类似的拆分策略。

通过拆分大键,可以将大的值分割为小的部分,这样可以更好地利用Redis的内存和性能。这种拆分策略可以根据实际情况进行调整,以满足存储和访问的需求。

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

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

相关文章

堆体系结构概述

1、逻辑概述 2、堆会出现的异常 3、物理上划分 (1)新生区 新生区是类的诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。新生区又分为两部分: 伊甸区&#xff0…

Goby 漏洞发布|WordPress User Post Gallery 插件 upg_datatable 远程代码执行漏洞(CVE-2022-4060)

漏洞名称:WordPress User Post Gallery 插件 upg_datatable 远程代码执行漏洞(CVE-2022-4060) English Name:WordPress plugins User Post Gallery upg_datatable RCE Vulnerability (CVE-2022-4060) CVSS core: 9.8 影响资产数…

Observability:如何把 Elastic Agent 采集的数据输入到 Logstash 并最终写入到 Elasticsearch

在之前的文章 “安装独立的 Elastic Agents 并采集数据 - Elastic Stack 8.0”,我们详述了如何使用 No Fleet Server 来把数据写入到 Elasticsearch 中。在今天的文章中,我们来详述如下使用 Elastic Agents 在独立(standalone)模式…

Gradio Blocks:自定义交互式Web应用和演示

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…

GitPySearch: 全局Python代码搜索工具

一 、背景 在某些情况下,我们需要快速了解哪些项目包含特定的配置,例如使用了fastjson库或数据库的连接配置。然而,在GitLab上逐个代码仓库进行搜索是非常耗时的。为了提高效率,我们开发了一个Python脚本工具,用于实现…

PostgreSQL的优势:为何它成为主流数据库管理系统

PostgreSQL的优势:为何它成为主流数据库管理系统 Stack Overflow 2023年报告PostgreSQL和MySQL同异我们在开发中如何选择PostgreSQL和MySQL呢? 摘要:本文主要比较了PostgreSQL和MySQL这两个流行的关系型数据库管理系统。我们首先介绍了它们的…

屏蔽箱的材质结构和使用事项介绍

屏蔽箱是一种用于屏蔽机电波干扰的设备,通常用于电磁兼容测试、天线测试、短波收发等需要屏蔽电磁辐射噪声的场合。这种箱子通常由导电或者导磁材料制成,内部配备高效屏蔽材料,能够在一定范围内有效地屏蔽电磁波辐射,避免电磁波干…

详细介绍mysql索引类型

目录 Normal 普通索引Unique 唯一索引Full Text 全文索引SPATIAL 空间索引btree索引和hash索引的区别在实际操作过程中,应该选取表中哪些字段作为索引? Normal 普通索引 表示普通索引,大多数情况下都可以使用 Unique 唯一索引 表示唯一的&…

Linux内核内存管理源码分析之init-mm.c(2)

接前一篇文章:Linux内核内存管理源码分析之init-mm.c(1) 本文内容参考:https://www.cnblogs.com/mysky007/p/12317831.html 上回说到了swapper_pg_dir和init_top_gpt。再次给出内核源码中init_top_gpt的说明,在Documen…

【基础】MQTT -- MQTT 特性:QoS、Retained 消息、LWT 以及 Keepalive

MQTT -- MQTT 特性:QoS、Retained 消息、LWT 以及 Keepalive QoS 及其最佳实践MQTT 协议中的 QoS 等级QoS 0QoS 1PUBACK 数据包 QoS 2PUBREC 数据包PUBREL 数据包PUBCOMP 数据包 实际的订阅者 QoSQoS 的最佳实践QoS 与会话QoS 的选择 Retained 消息LWT 遗嘱消息Keep…

FPGA_学习_12_IP核_FIFO

FIFO(Frist Input Frist Output),即先入先出,也是一种存储器,一般做数据缓冲。FIFO和 RAM的共同点在于都能存储数据、都有控制写和读的信号;不同点在于 FIFO 没有地址,所以不能任意指定读取某一个数据,数据只能按照数据…

一个女孩从软件测试工程师到主管的成长

说实话,我做测试工作的时间不是很长,学完软件测试工程师的课程后,到现在也就是一年多的时间吧,不过,我愿意自己学习和工作中积累起的这些点滴与大家分享。 如果你想学习自动化测试,我这边给你推荐一套视频…

C语言之程序环境和预处理(1)

本章主要以图片和文字的形式给大家讲解 程序的翻译环境和程序的执行环境 在ANSI C的任何一种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境,它用于实际执行代码 2. 详解编译…

东南亚骑行类目热销品出炉!Shopee/Lazada跨境卖家有哪些优势产品可做?

菲律宾/巴西是Lazada/Shopee骑行品类卖家体量最大的2个站点,新加坡/越南/马来西亚紧随其后. 体量:在东南亚,菲律宾与新加坡对骑行的需求最强烈,其次是越南,三地总订单占总体70%以上,在南美地区&#xff0c…

Revit碰撞检查:Navisworks“复合对象碰撞”的使用

一、Navisworks 中碰撞检查中“复合对象碰撞”有什么用? 通常情况下我们使用 Revit 做好了模型,然后使用 Navisworks这款软件进行碰撞检查等优化工作。因为 Navisworks 相对于 Revit的软件数据要“轻”很多,可以让多专业的模型都在一起导入来进行全专业…

对接口进行限流?

在高并发的情况下,我们可以把消息放入队列,在从队列消费,达到限流的目的。但这里说的限流指的是当我们请求其他服务器接口,防止高并发下把对面服务器压垮,于是对我们要求每秒限制在100QPS。 如果使用springCloud可以用…

准备换工作跳槽面试人一定要看的的18条忠告

1、如果想好要跳槽就别犹豫,不用纠结太多外在因素,很多事情只有去做了才知道。(当然,如果你是非某家公司不可的话,那可以慢慢等待机会) 2、关于跳槽的渠道,主要有四种:直接被公司挖…

测试自动化的演进,从录制回放到对象映射

概要:在短时间的市场化和短期冲刺的文化中,测试人员通过使用测试自动化实践和工具保持同步是至关重要的。本文跟踪从基于脚本的测试与硬编码数据到自动化框架的转变,探索测试自动化的开始和到今天的演变 - 并且可能的未来走向。 今天的软件市…

Qt之QDial选择器

文章目录 前言一、QDial是什么二、操作api信号与槽示例代码总结 前言 Qt是一种流行的跨平台的C GUI应用程序开发框架,用于构建图形用户界面(GUI)和其他桌面应用程序。QDial是Qt框架中的一个小部件,用于创建旋转式的拨号器。本文将介绍如何使用QDial进行…

ChatGLM Efficient Tuning效率调试PEFT

ChatGLM Efficient Tuning 基于 PEFT 的高效 ChatGLM-6B 微调。 [ English | 中文 ] 更新日志 [23/06/05] 现在我们实现了 4 比特的 LoRA 训练(也称 QLoRA)。请尝试使用 --quantization_bit 4 参数进行 4 比特量化微调。(实验性功能&#…