大厂面试官问我:Redis中热key和大key是怎么解决的?【后端八股文五:Redis热key和大key八股文合集】

  往期内容:

大厂面试官问我:Redis处理点赞,如果瞬时涌入大量用户点赞(千万级),应当如何进行处理?【后端八股文一:Redis点赞八股文合集】-CSDN博客

大厂面试官问我:布隆过滤器有不能扩容和删除的缺陷,有没有可以替代的数据结构呢?【后端八股文二:布隆过滤器八股文合集】-CSDN博客

大厂面试官问我:Redis持久化RDB有没有可能阻塞?阻塞点在哪里?【后端八股文三:Redis持久化八股文合集】-CSDN博客

大厂面试官问我:Redis内存淘汰,LRU维护整个队列吗?【后端八股文四:Redis内存淘汰策略八股文合集】-CSDN博客

本文为【Redis热key和大key八股文合集】初版,后续还会进行优化更新,欢迎大家关注点赞评论交流~

大家第一眼看到这个标题,不知道心中是否有答案了?在面试当中,面试官经常对项目亮点进行深挖,来考察你对这个项目亮点的理解以及思考!这个时候,你如果可以回答出面试官的问题,甚至是主动说出自己的思考,那在面试中是大大加分的~

Redis的热key

热key:
某个Key接收到的访问次数、显著高于其它Key时,称之为热Key。

热key带来的问题:
大量请求直接打过来,服务器可能会扛不住,造成缓存击穿从而直接打挂后端存储(数据库),影响其他使用后端存储的业务。
可能使得redis的集群失去意义,Redis Cluster中各node流量不均衡造成Redis Cluster的分布式优势无法被利用,一个分片负载很高而其它分片十分空闲。

产生原因:
未定期清理数据,没有设置过期时间,造成了如hash类型中key中的成员不断增加。
流量陡增,如出现某款爆款商品等(热key)。
bug,代码的业务逻辑上对key的成员只增不减也未设置过期时间。

热key的过期问题

1、手动删
2、通过Redis配置动态过期时间:
Redis提供了一个叫做“动态过期时间”的功能,可以在key即将过期时,重新计算过期时间,并通过Redis的expire命令设置新的过期时间。
3、使用Redis集群:
Redis集群是多个Redis节点的集合,每个节点都存储部分数据,整个集群作为一个虚拟服务器来对外提供Redis服务。在Redis集群中,热点key会被分配到不同的节点进行存储,从而避免了单节点内存溢出的问题。
4、使用Redis的LRU机制:
Redis 提供了一种名为“最近最少使用”的数据淘汰机制(LRU),可以将长时间不使用的热点key清除出Redis缓存。

Redis热Key问题怎么解决?


热key的处理方法有三种:
 

(1)复制:
在使用redis集群时,可以将热key复制多份,每个redis节点上存放一份,这样不存在请求的重定向使得压力全部定向到单个节点,能有效减轻单节点的压力。缺点是要进行复制的画只能在代码层手动操作,而且复制多份存放后会存在数据一致性问题。因此复制方案只能用于临时解决线上问题。
(2)读写分离:
热key多数是读热key的操作,读写分离能保证从节点中数据的一致性,并且能轻松的横向扩展,能有效的分散压力,只是有点浪费资源,因为读写分离每个从节点上存的都是一样的数据。
(3)多级缓存:
当热key数量不多,比如电商平台促销活动,热key都集中在少部分key上面,为此做读写分离增加机器性价比不高,使用多级缓存是个不错的解决方法。具体实现思路两种:
1.本地缓存,redis和业务服务器之间增加一个中间层(proxy),专门用来进行热key探查,这个proxy专门用来监视redis来统计达到预设的热key阈值的key,统计好后推送给业务服务器,让业务服务器存在本地缓存。
2.单独缓存,将proxy探查到的热key推送到单独的一个缓存热key的redis上去,如果扛不住,热key服务器再横向扩容,当然这个方案也是单独增加了服务器结点去处理热key的,除非保证系统中经常会有热key出现,不然的话使用本地缓存性价比更高。
使用多级缓存会存在一个问题,因为每次推送之间有时间间隔,缓存中的数据和redis中的数据不是呈现强一致性的,而是呈现最终一致性的。这种代价也是不得不接受的,在使用缓存的时候注意不要拿缓存做逻辑,只用来做查询即可。

Redis的热key怎么存放?

可以使用带有过期时间的键值对来存储热key,合理设置过期时间,让热key定期失效。

对于写入频繁的热key,可以考虑使用分布式锁或队列机制来限流。

对于读取频繁的热key,可以使用缓存策略,例如LRU/LFU等淘汰策略来减轻Redis的压力。

如何解决热key带来的redis宕机问题(热key读,热key写) / 一个热key导致单台机访问流量过高,该怎么办?

采用Redis集群或者Redis Sentinel架构,将数据分散到多个节点上,避免单点故障。

为热key设置合理的过期时间,让热key定期失效。

使用分布式锁或限流机制来控制对热key的写入请求。

对于读取频繁的热key,可以使用本地缓存或者CDN来分担Redis的压力。

Redis如何分析热key?key的占用大小?

可以使用Redis的info命令查看各个key的访问频率,从而识别出热key。

也可以使用Redis Enterprise或者其他监控工具,对Redis的访问情况进行分析,定位热key。

对于key的占用大小,可以使用object encoding命令查看。

如果分布式数据库中某一个分片具有热key导致一直被访问怎么去解决

采用sharding技术,将数据按照certain规则分散到不同的分片上,避免单一分片承担过大的访问压力。

对于频繁访问的热key,可以使用缓存机制,将数据缓存在应用层或者其他缓存层,减轻数据库的压力。

监控各个分片的访问情况,及时发现和处理热key问题。可以考虑将热key迁移到其他分片上。

Redis的大Key

这个问题就是Redis中某个key的value过大,所以Big Key问题本质是Big Value问题,导致Redis的性能下降或者崩溃。

产生原因

存放不合理,存储了不适合存放在内存中的数据,如用key存放音频视频这一类大体积二进制文件(大key)。
设计不合理,造成个别key中成员过多。(大key)。

性能下降原因


因为Redis需要将大key全部加载到内存中,这会占用大量的内存空间,会降低Redis的响应速度,这个问题被称为Big Key问题。

在Redis中,大key通常是由以下几种原因导致的:

对象序列化后的大小过大

存储大量数据的容器,如set、list等

大型数据结构,如bitmap、hyperloglog等
(如果不及时处理这些大key,它们会逐渐消耗Redis服务器的内存资源,最终导致Redis崩溃。)

或者

大key:
含有较大数据或含有大量成员的Key称之为大Key,常见的大key如:
String类型的Key值大于10kb
list、set、zset、hash的成员个数超过5000
list、set、zset、hash的成员数量虽然只有1000个但这些成员的value总大小为100MB

排查方法


Redis自带的 BIGKEYS 命令可以查询当前Redis中所有key的信息,对整个数据库中的键值对大小情况进行统计分析

由于BIGKEYS命令需要扫描整个数据库,所以它可能会对Redis实例造成一定的负担。在执行这个命令之前,请确保您的Redis实例有足够的资源来处理它,建议在从节点执行。

解决方案,以及如何避免

(分段,切割,序列化)
(1)分割大key
将Big Key拆分成多个小的key。这个方法比较简单,但是需要修改应用程序的代码。就像是把一个大蛋糕切成小蛋糕一样,有点费力,但是可以解决问题。
或者尝试将Big Key转换成Redis的数据结构。例如,将Big Key转换成Hash,List或者Set等数据结构。

(2)对象压缩
如果大key的大小主要是由于对象序列化后的体积过大,我们可以考虑使用压缩算法来减小对象的大小。Redis自身支持多种压缩算法,例如LZF、Snappy等。

(3)直接删除
如果你使用的是Redis 4.0+的版本,可以直接使用 unlink命令去异步删除。4.0以下的版本 可以考虑使用 scan ,分批次删除。

无论采用哪种方法,都需要注意以下几点:

避免使用过大的value。如果需要存储大量的数据,可以将其拆分成多个小的value。就像是吃饭一样,一口一口的吃,不要贪多嚼不烂。

避免使用不必要的数据结构。例如,如果只需要存储一个字符串,就不要使用Hash或者List等数据结构。

定期清理过期的key。如果Redis中存在大量的过期key,就会导致Redis的性能下降。就像是家里的垃圾,需要定期清理。

对象压缩

Redis大key的弊端?

内存占用高:大Key会占用大量Redis的内存空间,导致内存压力增大。

读写效率低:读写大Key需要的时间会更长,会影响Redis的整体响应速度。

容易引发阻塞:Redis是单线程模型,处理大Key时会阻塞其他请求。

数据传输慢:大Key在网络上的传输也会更慢,影响客户端的体验。

Redis删除大key,scan命令

(1)如何删除Redis中的大Key:

使用 DEL 命令删除大Key是非常低效的,因为它需要一次性读取整个Key的值,然后再进行删除。这种方式会导致Redis阻塞,影响其他命令的执行。

更好的删除方式是使用 UNLINK 命令。UNLINK 命令只会标记Key为待删除状态,并不会立即删除,这样可以避免阻塞问题。Redis会在后台异步删除这些Key。

(2)使用SCAN命令遍历和删除大Key:

SCAN 命令可以分批遍历Redis中的所有Key,而不会一次性读取所有Key,从而避免阻塞。

使用SCAN命令的步骤如下:

使用 SCAN 0 命令开始一个新的迭代。SCAN 命令会返回一个游标值,下次再次执行SCAN时需要带上这个游标值。

使用 SCAN <游标值> MATCH "大Key" COUNT 100 命令来遍历包含"大Key"的Key。COUNT 参数指定每次返回的Key数量。

对于遍历到的大Key,使用 UNLINK 命令进行删除。

重复步骤2-3,直到SCAN返回的游标值为0,表示遍历完成。

(3)使用管道(Pipeline)加速删除:

除了SCAN命令,您还可以使用Redis的管道(Pipeline)特性来批量删除大Key。

管道可以将多个命令打包发送到Redis,从而提高效率。您可以编写一个脚本,使用SCAN命令遍历大Key,然后将这些Key通过管道一次性删除。

Redis为什么有大key的问题,mysql没有?

Redis是基于内存的NoSQL数据库,它将整个数据集加载到内存中,所以Key和Value的大小会直接影响Redis的性能和内存占用。

而MySQL是基于磁盘的关系型数据库,它可以处理的数据量更大,因为数据不需要全部加载到内存中。

若大 Key 读取速度时间长达 60s,与此同时 Redis 还会做其他事情吗,通过什么实现这样并行的


Redis是单线程模型,当处理大Key读取时,其他请求也会被阻塞等待。不过Redis 5.0引入了多线程I/O模型,可以在某种程度上缓解这个问题。

redis有大key会发生什么(读写耗时高),如何排查大key

大Key会占用大量内存,影响Redis的性能和吞吐量。同时读写大Key也会耗费大量时间,导致Redis响应变慢。

可以使用Redis的INFO命令查看内存使用情况,或者使用OBJECT命令查看某个Key的大小。也可以使用第三方工具如redis-cli-monitor来实时监控Key的访问情况。

Redis的key和value大小有限制吗

Key 的大小限制:

Redis 的 Key 最大长度为 512MB。这意味着您可以存储最多 512MB 的 Key。

Value 的大小限制:

Redis 对 Value 的大小没有硬性上限,理论上可以存储高达 512MB 的 Value。

但在实际使用中,建议 Value 的大小不要超过 1MB,否则会影响 Redis 的性能。

Redis中打散了大key怎么查找(管道方式),除了管道还有没有其他的方式

(1)使用 KEYS 命令配合正则表达式:

如果事先知道被拆分的大Key都有一个共同的前缀,可以使用 KEYS 命令配合正则表达式来查找。

例如,如果大Key都是以 "mykey:" 为前缀,可以使用命令 KEYS "mykey:*" 来查找。

然后再通过管道或循环的方式批量删除这些Key。

(2)使用 SCAN 命令遍历:

SCAN 命令可以分批遍历Redis中的所有Key,不会一次性读取所有Key,从而避免阻塞。

可以使用 SCAN 0 开始一个新的迭代,然后使用 SCAN <游标值> MATCH "mykey:*" COUNT 100 来遍历以 "mykey:" 为前缀的Key。

对于遍历到的Key,再通过循环或管道的方式进行批量删除。

(3)结合 LUA 脚本:

还可以编写一个 LUA 脚本,在服务端执行复杂的查找和删除逻辑。

例如,使用 SCAN 命令遍历Key,并将匹配的Key通过 UNLINK 命令进行删除。这样可以进一步优化性能。

(4)使用Redis客户端库提供的工具:

一些Redis客户端库,如 Redis-py 和 Jedis,都提供了工具类来执行批量Key删除操作。

Redis大key问题,为啥慢,主要影响了什么

  • 大Key会占用更多内存,导致内存管理复杂化,增加内存碎片的风险。
  • 大Key的读写操作会阻塞Redis的主线程,影响其他命令的执行。
  • 大Key会增加网络传输的负担,导致客户端-服务器之间的通信延迟增加。
  • 大Key可能会导致 RDB 和 AOF 等持久化过程变慢,增加 Redis 的停机时间。

Redis大Key大概是多少

  • 一般认为,Redis中的大Key通常指超过 1MB 的Key-Value。
  • 1MB 以下的Key-Value通常不会对Redis性能产生很大影响。
  • 但具体多大算"大Key",需要根据您的业务场景、Redis服务器配置等因素来判断。

高ops的大val的key的解决方法

  • 对于高OPS且Value较大的Key,可以考虑以下方式优化:
  • 使用Redis的Stream数据结构,将大Value拆分成多个小块进行存储和传输。
  • 利用Redis的发布订阅机制,将大Value异步推送给订阅者,而不是直接返回给客户端。
  • 将大Value存储在外部存储系统(如对象存储),在Redis中只保留指向外部存储的引用。

   ---------------------------------------------------------------------------------------------------------------

后期新的八股文合集文章会仅粉丝可见,感兴趣的小伙伴可以点个关注~

 更多精彩内容以及一手消息请关注公众号:绝命Coding

公众号私信回复“免费资料”可免费获取简历模板以及技术亮点合集等免费资料

  • 67
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值