上一篇文章讲了Redis的热点key问题,本篇介绍Redis大Key问题的概念,大Key问题产生的原因、危害以及解决大Key问题的思路;

1. 什么是大key?多大算大key?

其实关于"大key"这个名词,这里就有个误区了,所谓的大key问题是指某个key的value比较大,所以本质上是大value问题;这样就对上了,key往往是固定的,一般根据key前缀和业务属性拼接而成,而value往往不是固定的,在服务运行期间被修改,因此是可能导致value变得很大的;

设想一种场景,在线音乐APP中,某个歌单有很多用户收藏,假如有这样的数据结构:

  • 歌单和用户之间的映射关系采用redis存储;
  • redis的key是歌单ID,长度可控且很小;
  • redis的value是个List,List包含了关注了该歌单的用户ID;
  • 用户可能很多,如果该key要存放所有关注歌单的用户ID,就会导致List长度不可控变得很长;

这下明白啥是大key问题了吧!

到底多大的value认为是大key呢?

Redis中有常见的几种数据结构,每种结构对大key的定义不同,通常以Key的大小和Key中成员的数量来综合判定,例如:

  • key本身的数据量过大:value是String类型时,Value 的字节大小大于10 KB;
  • key中的集合元素数过多:value是ZSET、Hash、List、Set等集合类型时,它的成员数量超过1w个;
  • Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的Value(值)总大小为100 MB

上述的定义并不绝对,主要是根据value的成员数量和value的字节数来确定,业务可以根据自己的场景也确定标准;

2. 大key的危害?

我们都知道,Redis的一个典型特征就是:核心工作线程是单线程。

单线程中请求任务的处理是串行的,前面完不成,后面处理不了,同时也导致分布式架构中内存数据和CPU的不平衡;因此Redis的大key可能带来以下问题:

  • 执行大key命令的客户端本身,耗时明显增加,甚至超时;
  • Redis内存达到maxmemory参数定义的上限,引发操作阻塞或重要的Key被逐出,甚至引发内存溢出(Out Of Memory)。
  • 执行大key相关读取或者删除操作时,会严重占用带宽CPU,影响服务器上的其他客户端;
  • 集群架构下,大key本身的存储带来分布式系统中分片数据不平衡,,CPU使用率也不平衡,某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡
  • 大key有时候也是热key,读取操作频繁,影响面会很大
  • 执行大key删除时,在低版本redis中可能易造成主库较长时间的阻塞,进而可能引发同步中断或主从切换;

这样看来大key的影响还是很明显的,最典型的就是:阻塞线程、并发量下降、导致客户端超时、服务端业务成功率下降;

3. 大key一般是如何产生的?

大key的产生往往是业务方设计不合理,没有预见vaule的动态增长问题;造成大key问题的原因一般有:

  • 在不适用的场景下使用Redis,易造成Key的value过大,如使用String类型的Key存放大体积二进制文件型数据;
  • 业务上线前规划设计不足,没有对Key中的成员进行合理的拆分将大key变成小key,从而造成个别Key中的成员数量过多;
  • 集合类数据结构一直往value里面塞数据,没有删除机制,未定期清理无效数据,造成如HASH类型Key中的成员持续不断地增加;
  • 使用LIST类型Key的业务消费侧发生代码故障,造成对应Key的成员只增不减;

4. 如何发现大key?

(1)增加内存&流量&超时等指标监控

由于大key的value很大,执行读取时可能阻塞线程,这样Redis整体的QPS会下降,并且客户端超时会增加,网络带宽会上涨,配置这些报警可以让我们发现大key的存在;

(2)bigkeys命令

使用bigkeys命令以遍历的方式分析Redis实例中的所有Key,并返回整体统计信息与每个数据类型中Top1的大Key;

(3)redis-rdb-tools

Redis-rdb-tools是通过Python编写,支持定制化分析Redis RDB快照文件的开源工具;使用redis-rdb-tools离线分析工具来扫描RDB持久化文件,虽然实时性略差,但是完全离线对性能无影响;

(4)集成化可视化工具

基于某些公有云或者公司内部架构的redis一般都会有可视化的页面和分析工具,来帮助我们定位大key,当然页面底层也可能是基于bigkeys或者rdb文件离线分析的结果;

5. 处理大key问题的思路?

根据大key的实际用途可以分为两种情况:可删除和不可删除;解决思路如下图:

(1)删除/清理大key

如果发现某些大key并非热key就可以在DB中查询使用,则可以在Redis中删掉;

  • 当Redis版本大于4.0时,可使用UNLINK命令安全地删除大Key,该命令能够以非阻塞的方式,逐步地清理传入的Key;
  • 当Redis版本小于4.0时,避免使用阻塞式命令KEYS,而是建议通过SCAN命令执行增量迭代扫描key,然后判断进行删除;

Redis UNLINK 命令类似与 DEL 命令,表示删除指定的 key,如果指定 key 不存在,命令则忽略;UNLINK 命令不同与 DEL 命令在于它是异步执行的,因此它不会阻塞;UNLINK 命令是非阻塞删除,非阻塞删除简言之,就是将删除操作放到另外一个线程去处理;

Redis Scan 命令用于迭代数据库中的数据库键;SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程;

对过期数据进行定期清理

堆积大量过期数据会造成大Key的产生,例如在HASH数据类型中以增量的形式不断写入大量数据而忽略了数据的时效性;可以通过定时任务的方式对失效数据进行清理;在清理HASH数据时,建议通过HSCAN命令配合HDEL命令对失效数据进行清理,避免清理大量数据造成Redis阻塞;

(2)压缩和拆分key

a. 当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗;

b. 当value是string,压缩之后仍然是大key,则需要进行拆分,一个大key分为不同的部分,记录每个部分的key,使用multiget等操作实现事务读取。

c. 当value是list/set/hash等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片;在Redis集群架构中,拆分大Key能对数据分片间的内存平衡起到显著作用;

(3)监控Redis的内存水位

可以通过监控系统设置合理的Redis内存报警阈值进行提醒,例如Redis内存使用率超过70%、Redis的内存在1小时内增长率超过20%等;通过此类监控手段,可以提前规避许多问题,例如LIST数据类型的消费程序故障造成对应Key的列表数量持续增长,将告警转变为预警从而避免故障的发生;

参考:

发现并处理Redis的大Key和热Key - 云数据库 Redis - 阿里云

解决了Redis大key问题,同事们都夸他牛皮

Redis——大Key问题相关推荐

  1. 深度评测丨GaussDB(for Redis)大Key操作的影响

    本文分享自华为云社区<墨天轮评测:GaussDB(for Redis)大Key操作的影响>,作者: 高斯 Redis 官方博客. 在前一篇文章<墨天轮评测:GaussDB(for R ...

  2. 技术解读丨分布式缓存数据库Redis大KEY问题定位及优化建议

    摘要:如何定位分布式缓存数据库Redis大KEY问题,实操案例带你掌握优化方法. [背景] 访问Redis 5.0 cluster集群出现OOM报错,报错信息为(error) OOM command ...

  3. Redis 大key与热key

    目录 Redis中BigKey解决方案 什么是BigKey? 大key场景 大key问题 如果redis的key较长时,会产生什么样的影响呢? 如何查看Redis中的bigKey? 查看所有BigKe ...

  4. Redis大key 问题

    背景 双十一大促期间, 收到客服反馈通知,说 APP 领券接口缓慢.找到一个case,通过调用链路发现,是操作redis 缓慢,并且还搜到一些redis 异常. 最后定位到原因:是发券场景下拿redi ...

  5. 解决Redis大key问题,看这一篇文章就够了

    作者 | 个推数据库工程师  嘉木 个推作为国内第三方推送市场的早期进入者,专注于为开发者提供高效稳定的推送服务,经过9年的积累和发展,服务了包括新浪.滴滴在内的数十万APP.由于我们推送业务对并发量 ...

  6. 阿里云redis大key搜索工具

    https://yq.aliyun.com/articles/117042 Redis提供了list.hash.zset等复杂类型的数据结构,业务在使用的时候可能由于key设计不合理导致某个key过大 ...

  7. Redis大key问题与scan命令

    简介 前面不是写了一篇点赞功能的一种实现的文章吗 当时也提出了一些问题,今天就来解决其中的部分问题 开始 先讲一讲背景吧,以免没看过之前文章的迷惑 还是以点赞功能为话题,这里主要解决之前存在的大key ...

  8. 【转自聊聊架构公众号】 Redis大key图形化统计及展示

    原标题:不管你的Redis集群规模有多大,都是时候思考下如何提升资源利用率了 内容来自"聊聊架构"公众号. 董明鑫,雪球 SRE 工程师,主要负责保障雪球稳定性.提升资源利用率及提 ...

  9. 删除docker中redis 大key(模糊查询)

    查看所有      docker ps -a    查看运行的    docker ps    重启          docker restart id 重启   docker restart 79 ...

最新文章

  1. 二本学生连发10篇SCI直博香港城大,被质疑「灌水」,本人回应!
  2. Solarium简易使用
  3. linux系统core dump设置,linux coredump设置
  4. Oracle数据文件、用户、schema、实例
  5. STM32迷你板UCOSII系统移植
  6. WPF学习笔记(二):初学者避坑实录
  7. charles代理手机调试_H5开发 移动端 调试之 Charles 抓包 和 Map Remote
  8. RUNOOB python练习题13 水仙花数
  9. 一个优秀的可定制化Flutter相册组件,看这一篇就够了
  10. 8_less中的内置函数
  11. Nginx 反向代理可以缓存 HTTP POST 请求页面吗?
  12. html.actionlink 锚点,razor - 从@ Html.ActionLink MVC 4将参数传递给控制器
  13. 5. JavaScript RegExp 类型
  14. 2021计算机视觉-包揽所有前沿论文源码 -上半年
  15. SmartQ 智器—公司介绍
  16. python转化时区
  17. 企鹅的面包(简化版)
  18. 第四期单独赠书,书籍翻倍,给你留了一本。
  19. 阿里云搭建svn服务器
  20. 网站优化过程中外链如何建设

热门文章

  1. 微信小程序使用weapp-qrcode生成二维码
  2. uni-app 商城 的sku算法(vue)
  3. 【iOS】设计尺寸规范(更新至iPhone 11、iPhone 11 Pro、iPhone 11 Pro Max)
  4. [小知识] 获取浏览器UA标识
  5. php如何让图片铺满屏幕,如何解决js获取屏幕大小并且让图片自适应的方法
  6. 当语音遇到人工智能,走进《智能语音时代》
  7. Ubuntu Kylin 20_10 在VMware Workstation Pro上安装
  8. 如何对大数据进行分析和处理?_光点科技
  9. MFC - LNK2001 “无法解析的外部符号”的几种情况及解决办法
  10. 不用PS,一键生成熊猫头表情包