redis内存被打爆了

一次基于redis做队列消费cannel的binlog导致内存被打爆的场景分析

问题复现流程图:

  • 100万次 SQL 更新 → 100万个 Binlog 事件
  • 100万个事件 → 100万个队列任务(都在同一个业务队列中)
  • 100万个任务 → 100万个监控 Key(Horizon 监控每个任务)

每次 MySQL UPDATE 都会产生一个 Binlog 事件 100万次 UPDATE = 100万个 Binlog 事件

  • Canal 为每个 Binlog 事件创建一个队列任务
php 复制代码
foreach ($binlogEvents as $event) {
    // 每个事件都创建一个任务,塞到同一个队列
    Redis::lpush('ai_vending_horizon', json_encode([
        'id' => generateUUID(),
        'event' => $event,
        'timestamp' => time()
    ]));
}

horizon:laravel框架的queue队列管理服务 支持队列中每个任务的监控和管理 `

  • 暂停/恢复队列
  • 重试失败任务
  • 清空队列
  • 查看任务详情`
  • 任务超时

等等

Laravel Horizon 本身是个很好的工具,但在事故中:

  • 监控开销过大:每个任务都创建多个监控 Key
  • 缺乏批量处理:没有针对大批量任务的优化
  • 内存管理缺失:没有监控 Key 数量的限制
  • 缺乏redis内存监控告警

Horizon都干了啥?

arduino 复制代码
// 每个任务都会创建这些监控 Key
ai_phone_horizon:{task_id}           // 任务状态
ai_phone_horizon:{task_id}:metrics   // 性能指标
ai_phone_horizon:{task_id}:runtime   // 运行时间
ai_phone_horizon:{task_id}:memory    // 内存使用
ai_phone_horizon:{task_id}:failed    // 失败信息
ai_phone_horizon:{task_id}:retries   // 重试次数

任务级别的监控的作用

diff 复制代码
// 需要知道每个任务的状态
- 任务是否成功执行?
- 任务执行了多长时间?
- 任务消耗了多少内存?
- 任务失败了吗?
- 任务重试了几次?

监控开销计算

ini 复制代码
100万个任务 × 每个任务6个监控Key = 600万个 Redis Key

同时业务逻辑消费慢,任务被阻塞,导致任务队列数据数据越来越多,越来越大,变成一个吃内存的超级大key

优化、优化

相关推荐
天若有情6731 天前
新闻通稿 | 软件产业迈入“智能重构”新纪元:自主进化、人机共生与责任挑战并存
服务器·前端·后端·重构·开发·资讯·新闻
清水1 天前
Spring Boot企业级开发入门
java·spring boot·后端
星释1 天前
Rust 练习册 :Proverb与字符串处理
开发语言·后端·rust
ZZHHWW1 天前
RocketMQ vs Kafka01 - 存储架构深度对比
后端
依_旧1 天前
MySQL下载安装配置(超级超级入门级)
java·后端
熊小猿1 天前
RabbitMQ死信交换机与延迟队列:原理、实现与最佳实践
开发语言·后端·ruby
淘源码d1 天前
什么是医院随访系统?成熟在用的智慧随访系统源码
java·spring boot·后端·开源·源码·随访系统·随访系统框架
武子康1 天前
大数据-147 Java 访问 Apache Kudu:从建表到 CRUD(含 KuduSession 刷新模式与多 Master 配置)
大数据·后端·nosql
2301_795167201 天前
玩转Rust高级应用 如何让让运算符支持自定义类型,通过运算符重载的方式是针对自定义类型吗?
开发语言·后端·算法·安全·rust
程序猿阿越1 天前
Kafka源码(七)事务消息
java·后端·源码阅读