首页 > 数据库 >2023-06-21:redis中什么是BigKey?该如何解决?

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

时间:2023-06-21 18:01:20浏览次数:49  
标签:遍历 06 21 SCAN Redis redis 游标 命令 bigkey

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的内存和性能。这种拆分策略可以根据实际情况进行调整,以满足存储和访问的需求。

标签:遍历,06,21,SCAN,Redis,redis,游标,命令,bigkey
From: https://www.cnblogs.com/moonfdd/p/17496842.html

相关文章

  • 【2023-06-20】十一周月
    20:00有时候随手的一件事,你并不知道会不会改变一个人。而我就是被别人改变的。                                                 ——彭清林今天二宝满十一周月了。小......
  • 6月21日
    完成情况:今天我开始了围棋游戏的代码编写。我先确定了游戏的需求和功能,并进行了代码的骨架搭建。我创建了项目文件夹并初始化了代码仓库。在这一天,我完成了游戏界面的显示和棋盘的绘制功能的基本实现。编译过程中没有出现语法错误或编译错误,得到了可执行文件。待解决问题:需要进一......
  • 什么是Redis 雪崩、缓存"鸡"穿、缓存穿透?及出现的原因,如何预防
    Redis雪崩:在某个时间段,Redis的部分节点或者全部节点都挂掉了,导致Redis无法提供服务,请求全部转移到后端数据库,从而压垮数据库的情况。Redis雪崩通常由于某些原因导致缓存中的数据批量失效或者过期,导致后续请求都落到了数据库上,使得数据负载和请求量急剧增大,最终导致数据库的性能急......
  • 2023.6.21 每日一题
    原题链接A:WunderFundRound2016(Div.1+Div.2combined)-FB:CodeforcesRound727(Div.2)-DB.PriceFixed-1600题目大意商店里有\(n\)个商品,价格为\(2\),至少要买第\(i\)件商品\(a_i\)个,同时如果我们总共买了超过\(b_i\)件商品,那么第\(i\)件商品......
  • MUR8060PT-ASEMI快恢复二极管MUR8060PT
    编辑-ZMUR8060PT在TO-247封装里采用的2个芯片,其尺寸都是140MIL,是一款高耐压大电流快恢复二极管。MUR8060PT的浪涌电流Ifsm为600A,漏电流(Ir)为10uA,其工作时耐温度范围为-55~150摄氏度。MUR8060PT采用抗冲击硅芯片材质,里面有2颗芯片组成。MUR8060PT的电性参数是:正向电流(Io)为80A,反......
  • [Leetcode] 0706. 设计哈希映射
    706.设计哈希映射点击跳转至leetcode题目描述不使用任何内建的哈希表库设计一个哈希映射(HashMap)。实现MyHashMap类:MyHashMap()用空映射初始化对象voidput(intkey,intvalue)向HashMap插入一个键值对(key,value)。如果key已经存在于映射中,则更新其对应的值v......
  • 如何利用Redis实现对数据去重?
    要使用Redis实现数据去重,可以利用Redis的Set数据结构和它的去重特性。下面是一种基本的方法:连接到Redis服务器:首先,确保你已经安装并正确地配置了Redis服务器,并且能够连接到它。创建一个Set:在Redis中,可以使用以下命令创建一个Set:SADDset_nameitem1item2item3...这里的set_name......
  • 基于Redis实现查找附近的人/排行榜
    引言   在日常使用的有些APP中,想什么微信,百度地图,可以可以搜寻附近的人,距离自己多远,以及在地图上我们可以搜索附近的某个地点,距离自己的位置。针对这种类似的功能,我们可以通过redis就能实现。redis在3.2版本之后也提供了地理位置的能力,使用redis可以轻松实现查找附近的人......
  • PG-DBA培训06:PostgreSQL数据定义与数据对象开发设计
    一、风哥PG-DBA培训06:PostgreSQL数据定义与数据对象开发设计本课程由风哥发布的基于PostgreSQL数据库的系列课程,本课程属于PostgreSQL数据库SQL开发与应用实战阶段之PostgreSQL数据定义与数据对象开发设计,学完本课程可以掌握索引类型,索引,约束,视图,序列,存储过程,触发器,游标,函数的创......
  • 低功耗国产蓝牙芯片 HS6621系列 支持蓝牙5.1
    HS6621CxC是一个功耗优化的蓝牙低功耗和专有的2.4ghz应用真正的芯片上系统(SOC)解决方案。它集成了一个具有蓝牙基带和丰富外设的低功耗射频收发器I0扩展。HS6621CxC还集成了电源管理,提供高效率电源管理。它的目标是2.4G蓝牙低功耗系统,人机界面设备(键盘、鼠标和遥控器),运动及休......