Redis中big keys发现与解决过程

 更新时间:2026年04月07日 08:49:16   作者:小码A梦  
文章从bigkeys的定义、产生原因、危害、如何发现以及处理方法等方面详细介绍了Redis中bigkeys的问题,bigkeys会导致请求响应慢、网络卡顿、数据丢失等问题,需要通过异步删除、拆分key等方法进行处理

在使用 Redis 时,可能会出现请求响应慢、网络卡顿、数据丢失的情况。排查问题的时候,发现是 big keys 的问题。

什么是 big keys

在 Redis 中,一个字符串类型最大可以达到 512MB,其他非字符串类型的集合类型(list、set、hash、zset等)可以存储 40 亿个(2^32-1),但在实际业务场景中,并不需要这么大的内存。而且对于一个请求量大的互联网软件,对数据的大小要求更加的严格。如果达到如下标准,就可以认定是 big keys 了:

  • String 类型的 key 对应的值超过 5 MB。
  • list、set、hash、zset等集合类型,集合元素个数超过 2000。

以上对 big keys 的判断标准并不是唯一,只是一个大题的标准。在实际业务开发中,对 big keys 的判断是需要根据具体的使用场景做不同的判断。比如操作某个 key 导致请求响应时间变慢,那么这个 key 就可以判定成 big keys。

big keys 是如何产生的

一般来说,big keys 的产生都是由于程序的设计不当,或者对数据的规模没有一个大体的估算。比如:

  • 统计类:例如统计某个网站的访问用户信息,网站的访问量越来越多,这个 key 的元素也会越来越大。变成了 big keys。
  • 社交类:例如某个大V微博粉丝量很大,如果不做合理的设计,也是 big keys。
  • 缓存类:一般缓存类的信息访问都比较频繁,是将从数据库查询出来的数据序列化到Redis缓存中,这里的缓存如果设计不当,或者为了方便,把所有的数据都存在一个 key 下,或者随着业务的扩大,对应的缓存也增多,也是形成 big keys。

以上几种类型都是在实际运维中遇到的。在开发中需要根据预估的数据大小来合理的设计缓存数据。

big keys 的危害

在系统中如果存在 big keys,会导致请求数据响应变慢、请求超时或者系统不稳定。

1、响应变慢、超时阻塞

  • Redis 是单线程工作的,同一时间只能处理一个请求,操作 big keys 时比较耗时,请求响应也变慢。
  • 其他请求也处于阻塞状态,导致请求超时。
  • 除了查询 big keys 比较耗时,删除 big keys 也会导致一样的问题。

2、网络拥塞

  • 请求单个 big keys 产生的网络流量比较大,假设一个 big keys 为 1MB,客户端每秒访问量是 1000,那么每秒产生 1000MB 的流量,普通的千兆网卡承受不了这么大的流量。
  • 而且一般会在单机部署多个Redis实例,一个 big keys 可能也会影响其他实例。

3、内存分布不均

  • Redis 集群模式中,key根据不同的hash嘈分配到不同的节点上,当大部分的 big keys 分布在同一个节点,导致内存倾斜在同一个节点上,内存分布不均。
  • 在水平扩容时,需要以最大容量的节为准,浪费内存。

如何发现 big keys

Redis4.0 后提供了 --bigkeys命令,比如:

./redis-cli --bigkeys

获取每个数据类型最大的 big keys,同时给出每个类型键的个数和平均大小。因为 Redis 是单线程工作的,为了减少对线上请求的影响,执行--bigkeys命令需要注意一下几点:

  • 最好在 slave 节点执行,因为 --bigkeys 也是扫描数据,会造成其他线程阻塞。
  • 使用 --i 参数,降低扫描的执行速度,比如 --i 0.1 表示 100 毫秒执行一次。
  • 只能统计每个数据类型最大的数据。

big keys 处理

异步删除 big keys

找到 big keys 之后,首先需要删除对应的big keys,但是使用 del 命令删除 big keys 是比较耗时的。Redis4.0 后可以使用 unlink 删除,和 del 命令相比,unlink 是非阻塞的异步删除。

非字符串的 big keys,使用 hscan、sscan、zscan 方式渐进式删除,同时要注意防止big keys 过期时间自动删除问题(例如一个 200 万的 zset 设置1小时过期,会触发del操作,造成阻塞)。

big key 拆分

字符串类型的数据是减少字符串的长度,将一个字符串拆成几个小的字符串。非字符串的是减少元素数量。这些都是讲一个 key 拆成多个 key,比如:

  • 字符串类型的数据,根据数据的属性拆分。比如商品信息,根据的类别拆分 key。
  • 非字符串类型的数据,根据数据的属性拆分,可以按照日期拆分,比如每天登录人的集合,按照日期拆分,key20220101、key20220102.

如果 big keys 无法避免,那获取数据尽量不要把所有的数据都取出来,就使用分段的方式取出数据。删除的方式也类似,分段删除数据。

总结

  • big keys 会造成请求变慢、网络阻塞、数据丢失的问题。
  • big keys 是字符串字节达到很大的数量(比如 5MB),非字符串类型元素类型达到 1000 个都可以判定成 big keys,具体还需要看具体的场景。
  • big keys 的产生可能由于设计不合理或者对数据大小估算错误,导致数据偏大。
  • 解决 big keys 先紧急使用异步删除 unlink 命令删除缓存。然后将单个 key 拆分成多个小 key。
  • 如果无法避免 big keys,就使用分段查询的方式查询数据。

要从几个方面分析:

  • big keys 会带来哪些问题。
  • big keys 一般怎么产生的,线上如果产生了big key,线上先怎么紧急处理。
  • 有哪些优化方案,各自有什么应用场景。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 基于Redis实现短信验证码登录功能

    基于Redis实现短信验证码登录功能

    对于我们用户来讲,我们在登陆一个APP的时候,有很多种登陆方式,比如"微信扫码"、"手机号登陆"、"支付宝扫码"、"账号密码登录",现在大多都会要求微信扫码登录或者是手机号验证码登录,所以本文给大家介绍了基于Redis实现短信验证码登录功能,需要的朋友可以参考下
    2025-01-01
  • Redis高并发缓存设计问题与性能优化

    Redis高并发缓存设计问题与性能优化

    本文详细介绍了Redis缓存设计中常见的问题及解决方案,包括缓存穿透、缓存失效(击穿)、缓存雪崩、热点缓存key重建优化、缓存与数据库双写不一致以及开发规范与性能优化,感兴趣的可以了解一下
    2024-11-11
  • Redis实现好友关注的示例代码

    Redis实现好友关注的示例代码

    本文主要介绍了Redis实现好友关注的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Redis官方可视化工具RedisInsight的安装使用详细教程(功能强大)

    Redis官方可视化工具RedisInsight的安装使用详细教程(功能强大)

    RedisInsight是Redis官方出品的可视化管理工具,可用于设计、开发、优化你的Redis应用。支持深色和浅色两种主题,界面非常炫酷,接下来通过本文给大家介绍Redis官方可视化工具RedisInsight的安装使用过程,需要的朋友可以参考下
    2022-04-04
  • React事件绑定的方式及区别详解

    React事件绑定的方式及区别详解

    React提供了多种方式来绑定事件处理函数,每种方式有其独特的特点和适用场景,理解 React中不同的事件绑定方式及其差异,不仅有助于编写高效的代码,也能在面试中展示你对React的深刻理解,本文将详细讲解React中常见的事件绑定方式,包括其区别、优缺点以及适用场景
    2024-12-12
  • Redis Lua同步锁实现源码解析

    Redis Lua同步锁实现源码解析

    这篇文章主要为大家介绍了Redis Lua同步锁实现源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • 聊聊使用RedisTemplat实现简单的分布式锁的问题

    聊聊使用RedisTemplat实现简单的分布式锁的问题

    这篇文章主要介绍了使用RedisTemplat实现简单的分布式锁问题,文中给大家介绍在SpringBootTest中编写测试模块的详细代码,需要的朋友可以参考下
    2021-11-11
  • redis和redission分布式锁原理及区别说明

    redis和redission分布式锁原理及区别说明

    文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,乐观锁存在数据库性能瓶颈,而Redission通过watchdog自动续期和Lua原子操作解决Redis锁的超时问题,推荐其在高并发场景下的可靠性与易用性
    2025-08-08
  • Redis键值设计的实践

    Redis键值设计的实践

    本文主要介绍了Redis键值设计的实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Redis+AOP+自定义注解实现限流

    Redis+AOP+自定义注解实现限流

    这篇文章主要为大家详细介绍了如何利用Redis+AOP+自定义注解实现个小功能:自定义拦截器限制访问次数,也就是限流,感兴趣的可以了解一下
    2022-06-06

最新评论