记一次redis使用问题

简介: 记一次redis使用问题

现象

redis-cluster某个分片内存飙升,明显比其他分片高很多,而且持续增长。并且主从的内存使用量并不一致。(个别可能导致服务无法启动)

分析可能原因

对于 redis 出现这种现象,一般都会从这个这几个方面考虑

  1. redis-cluster的bug (这个应该不存在)
  2. 客户端的hash(key)有问题,造成分配不均。(redis使用的是crc16, 不会出现这么不均的情况)
  3. 存在个别大的key-value: 例如一个包含了几百万数据set数据结构(这个有可能)
  4. 主从复制出现了问题。
  5. 其他原因

调查原因

  1. 经查询,上述1-4都不存在
  2. 观察info信息,有一点引起了怀疑: client_longes_output_list有些异常。
  3. 于是理解想到服务端和客户端交互时,分别为每个客户端设置了输入缓冲区和输出缓冲区,这部分如果很大的话也会占用Redis服务器的内存。

从上面的 client_longest_output_list 看,应该是输出缓冲区占用内存较大,也就是有大量的数据从Redis服务器向某些客户端输出。

于是,使用 client list 命令(类似于 mysql processlist)redis-cli -h host -p port client list | grep -v "omem=0",来查询输出缓冲区不为0的客户端连接,于是查询到祸首 monitor,于是豁然开朗。

monitor 的模型是这样的,它会将所有在 Redis 服务器执行的命令进行输出,通常来讲 Redis 服务器的 QPS 是很高的,也就是如果执行了 monitor 命令,Redis服务器在 Monitor 这个客户端的输出缓冲区又会有大量“存货”,也就占用了大量 Redis 内存。


概念详细介绍

这是 redis 的配置介绍,对于客户端内存限制

redis 客户端在于 redis 服务端相互交互时,服务端会为每个客户端分别设置输入缓存区和输出缓存区,我们知道 redis 是基于内存的非关系型数据库,所以这两部分缓存区的数据依然是保存在内存中,如果这两部分很大的话会占用 redis 很大的内存。模型图如下图所示:

使用 info 命令查看当前redis客户端连接数及当前缓存区的使用量

那么什么是输入缓存区和输出缓存区呢?

输入缓存区:用于保存客户端发送的请求,输入缓存区的大小会根据请求数据的大小动态变化,1GB 是输入缓存区最大的容量,如果超出最大容量该客户端便会被关闭。


输出缓存区:用于保存执行请求后的返回结果,每个客户端有两个缓存区,一个是固定客户端缓存区(用于保存那些长度比较小的返回值,如一些比较短的字符串或整数值);一个是可变客户端缓存区(用于保存那些长度比较大的返回值,如长度比较大的字符串、大集合等)。


服务器采用软性限制和硬性限制两种方式限制输出缓存区的大小。


软性限制:如果软性限制所设置的大小小于输出缓冲区的大小,且输出缓冲区的大小不大于硬性限制所设置的大小,那么服务器会使用客户端状态结构的 obuf_soft_limit_reached_time 属性来记录客户端达到软性限制的起始时间。之后服务器会继续监视客户端,如果这个缓冲区的大小一直超出软性限制,并且持续时间超过服务器设定的时长,那么服务器将会关闭这个客户端。相反地,如果输出缓冲区的大小在指定时间范围之内没有超过软性限制,那么这个客户端不会被关闭,并且 obuf_soft_limit_reached_time 属性的值也会被设置为 0。


如果输出缓存区的大小大于硬性限制,那么客户端会立即关闭。

在 redis 配置文件中,可以对软性限制和硬性限制进行设置:

第一行代码表示:对于 普通 客户端来说,限制为 0,也就是不限制。因为普通客户端通常采用阻塞式的消息应答模式,通常情况下不会导致 redis 输出缓存区数据堆积膨胀。


第二行代码表示:对于 slave 客户端来说,硬性限制是 256M,软性限制是当客户端缓冲区大小持续 60秒 超过 64M,则关闭客户端连接。


第三行代码表示:对于 Pub/Sub 客户端(也就是发布/订阅模式),硬性限制是 32M,当输出缓冲区超过 32M 时,会关闭连接。软性限制是当客户端缓冲区大小持续 60秒 超过 8M,则关闭客户端连接;

紧急处理办法

进行主从切换(主从内存使用量不一致),也就是 redis-cluster 的 fail-over 操作,继续观察新的 Master 是否有异常,通过观察未出现异常。

查找到真正的原因后,也就是 monitor,关闭掉 monitor 命令的进程后,内存很快就降下来了。

预防办法

  1. 修改客户端源代码,禁止掉一些危险的命令(shutdown, flushall, monitor, keys *),当然还是可以通过redis-cli来完成;

添加command-rename配置,将一些危险的命令(flushall, monitor, keys * , flushdb)做rename;

对 redis 使用中遇到的问题分享、学习分享很重要。

参考博文:


https://www.iteye.com/blog/carlosfu-2254154

目录
相关文章
|
存储 缓存 NoSQL
阿里云 Tair 联手 SGLang 共建 HiCache,构建面向“智能体式推理”的缓存新范式
本文系统剖析面向智能体推理的 KVCache 技术演进,针对传统机制在长上下文、多轮决策与多智能体协同中的状态膨胀、持久化缺失和缓存孤立三大瓶颈,介绍阿里云 Tair KVCache 团队联合 SGLang 社区推出的 HiCache 分层缓存体系。该方案通过显存-内存-3FS 多级卸载与全局共享,实现缓存命中率提升至80%,TTFT 降低56%,推理 QPS 翻倍,支撑智能体时代的大模型高效推理。
|
NoSQL 网络协议 数据库
为什么 Lettuce 会带来更长的故障时间
本文详述了阿里云数据库 Tair/Redis 将使用长连接客户端在非预期故障宕机切换场景下的恢复时间从最初的 900s 降到 120s 再到 30s的优化过程,涉及产品优化,开源产品问题修复等诸多方面。
70358 11
为什么 Lettuce 会带来更长的故障时间
|
消息中间件 Apache 数据安全/隐私保护
[ActiveMQ]修改默认密码
ActiveMQ使用的是jetty服务器, 在ActiveMQ目录下的conf/jetty.xml文件,vim打开 将property name为authenti...
2666 0
|
6月前
|
SQL 监控 关系型数据库
MySQL分区表:大规模数据管理的解决方案
本文深入解析了MySQL分区表的原理与实战应用,涵盖分区类型、管理策略及性能优化技巧,帮助用户提升查询效率和数据管理能力。
|
8月前
|
前端开发 搜索推荐 开发工具
通义灵码与颜色板生成器,为前端开发提供智能配色解决方案
在前端开发中,色彩搭配对用户体验和界面美观至关重要。通义灵码提供的颜色板生成器通过自动推荐配色方案、随机生成颜色组合及支持自定义调整,帮助开发者高效完成配色任务。该工具支持一键导出为 CSS 样式表,并提供简洁的中文指令交互方式,大大提升开发效率,助力开发者打造美观和谐的用户界面。
|
5月前
|
存储 弹性计算 双11
阿里云有哪些优惠券?上云礼包、学生优惠券、按量达标代金券、新客满减券等优惠券介绍
很多用户关心活动期间阿里云有哪些优惠券可以领取和使用?金额是多少?领取后如何使用?目前,新注册用户可领取的优惠券涵盖双11上云礼包(个人360元,企业1728元)、学生无门槛优惠券(300元)、按量达标返代金券(50元)、新客户专享满减券(10元)等、系统赠送券(160元/50元/10元不等),企业同时还可申请出海扶持抵扣金(3500元-100万元)、算力补贴优惠券(金额以审核发放为准)等。本文为大家介绍这些优惠券的具体金额、领取与使用规则等,以供参考。
699 12
|
消息中间件 测试技术 RocketMQ
消息队列 MQ产品使用合集之在异步发送消息函数sendMessage()中出现了错误,错误代码为-3,该如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
JavaScript 前端开发 索引
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
这段代码和说明介绍了JavaScript中数组的一些常用方法。函数接收三个参数:`item`(数组项的值)、`index`(项的位置,可选)和`array`(数组本身,可选)。示例展示了如何使用`filter()`过滤非空项、`forEach()`遍历数组、`map()`处理并返回新数组、`every()`检查所有元素是否满足条件、`some()`检查是否存在满足条件的元素、`find()`获取首个符合条件的元素值以及`findIndex()`获取其索引位置。这些方法都不会修改原数组。
446 0
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
|
SQL 关系型数据库 MySQL
「Go开源」goose:深入学习数据库版本管理工具
「Go开源」goose:深入学习数据库版本管理工具
「Go开源」goose:深入学习数据库版本管理工具
|
Prometheus 监控 Cloud Native
Prometheus结合Consul采集多个MySQL实例的监控指标
将 Prometheus 与 Consul 结合使用,实现对多个 MySQL 实例的自动发现与监控,不仅提高了监控的效率和准确性,也为管理动态扩缩容的数据库环境提供了强大的支持。通过细致配置每一部分,业务可以获得关键的性能指标和运行健康状况的即时反馈,进而优化资源配置,提高系统的稳定性和可用性。
691 3