消息积压:业务突然增长,导致消息消费不过来怎么办?

消息积压:业务突然增长,导致消息消费不过来怎么办?

消息积压指消息生产速度大于消费速度,导致消息在broker上存放。消息积压可能导致消息很久才被消费。对于时效性有要求的业务是不可容忍的。

消费者和分区的关系

  • Kafka中,一个分区只能有一个消费者,但一个消费者可以同时消费多个分区。
  • 如果有N个分区,最多有N个消费者,再增加消费者也不能提供消费速度
  • 如果不足N个消费者,一些消费者会从多个分区拉数据

这种设计无法通过无限增加消费者来解决消息积压问题。如果没有这种限制就不会有消息积压了

确定分区数量

  • 分区数量要保证生产者不会阻塞,同时消费者来的及消费消息
  • 可以通过压测或者观测消息集群性能来确定

解决方案

解决消息积压要区分是临时积压还是永久积压

  • 临时积压:是突然来的流量,导致消费者一时半会跟不上
  • 永久积压:则是消费者消费速率跟不上生产速率
  • 如果临时积压,并且消费者处理的时间可以接受,可以不解决
  • 如果接受不了,或是永久积压。就需要尝试解决。最简单的方案是增加消费者到分区数量一致

增加分区

如果消费者和分区数量一致可以尝试增加分区。

  • 增加新分区意味着可以增加新的消费者来增速

创建新的topic

有时候公司不允许增加分区,可以考虑创建新的topic

  • 准备一个新topic,消费老topic的同时也消费新的topic。等老topic数据消费完后完全切换到新topic
  • 或者创建新topic,把老topic上的消息转发到新topic上。只需要启动消费者消费新topic就可以了

创建新topic的难点是究竟需要几个分区,最佳办法就是压测来确定

新分区计算方式:假设所有生产者QPS是3000。一个消费者处理的QPS是200,那么就是3000÷200=15。考虑业务增长或者突发流量可以使用18到20个分区

优化消费者性能

不能增加消费者和分区的时候,可以考虑优化消费者性能,大体两种思路

  • 消费者部署更好的实例上(不是我们能左右的)
  • 优化消费者消费逻辑
方案
  • 最开始考虑同一个业务的消息可能被不同的消费者消费,就引入了分布式锁
  • 后面通过主动选择目标分区使相同业务总把消息发到同一分区,确保同一时间只有一个消费者处理一个业务的消息,就可以去掉分布式锁,没有分布式锁就不会因为等待分布式锁而导致消费速率下降

聚合消息和批量操作

  • 这种方式适用于消费者可以改造成批量接口的场景
  • 可以考虑不改造生产者,只改造消费者
  • 把消费者改造成批量消费、批量提交偏移量
  • 比如消费者一次性拉去100条消息,构造批量处理请求。请求处理成功后,再提交偏移量

异步消费(核心解决方案)

  • 消费者弄一个消费线程,负责从消息队列拉消息。拉到的消息立刻转发给一个线程池,线程池有一些工作线程处理消息。
  • 注意消息丢失的问题
消息丢失
  • 消息丢失:指消费者线程取出消息后,要消费下一条就要先提交当前这条。这时可能出现一个问题:消费者线程提交了,但是工作线程还没处理就挂了。因为已经提交了,就算重启也是从下一条开始消费
  • 解决方案:可以考虑批量提交的方法。消费者线程一次拉一批消息。比如说10条,然后不是立刻提交这10条消息,而是开十个线程并行处理这10条消息,等10条消息都处理完,再批量提交
  • 问题:批量提交效果很好,但是会带来重复消费和部分失败的问题
重复消费

消费者线程拉去一批消息后,如果还没提交就挂了。当消费者恢复后,就会拉取同一批继续消费。

  • 解决方案:保证处理消息的逻辑是幂等的。这样即使宕机导致消费被消费还没提交,也可以保证下次恢复时,重复处理不会引起业务问题
部分失败

要保证部分失败不会影响继续向前消费

  • 第一种做法是要求工作线程立即重试。比如重试三次,或者用一个新的异步线程来重试
  • 第二种做法是把消费失败的消息丢回消息队列,后面轮到它又会被处理,相当于重试
相关推荐
techdashen1 小时前
Arborium:把 tree-sitter 语法高亮打包成 Rust 文档生态的基础设施
开发语言·后端·rust
Profile排查笔记1 小时前
指纹浏览器环境异常排查:Fingerprint、Profile、Proxy、Session 和 Task Log 怎么看
前端·人工智能·后端·自动化
小强库计算机毕业设计1 小时前
源码分享Spring Boot + Vue3 的校园社团管理系统
java·spring boot·后端·计算机毕业设计
2301_801184751 小时前
kafka-zookeeper
分布式·zookeeper·kafka
阿新聊ai2 小时前
从 Prompt 到 Loop:AI 编程 Agent 四代循环的演进全景
人工智能·后端
im_lanny2 小时前
从 Function Calling 到 MCP:Agent 工具调用的三层境界与生产级安全护栏
后端
agent8972 小时前
Spring Boot 接口超时治理:从连接池、线程池到熔断限流的完整排查思路
java·spring boot·后端
Devin~Y2 小时前
抖音级短视频推荐与直播带货平台面试实战:从 Java 微服务到 RAG 智能客服全链路解析
java·spring boot·redis·spring cloud·kafka·agent·rag
雨师@3 小时前
go语言项目--实例化(图书管理)--005
开发语言·后端·golang
Aspiresky3 小时前
探索Rust语言之引用
开发语言·后端·rust