消息队列|Kafka消息积压
Fang 2025/4/14 后端消息队列
# 消息积压
消息积压是指消息生产速率大于消费速率,所以消息会在broker上存放着。消息积压可能会导致消息要等很久才会被消费,这对于一些业务来说损害很大。
特别是一些对消息消费时效性有要求的业务,几乎不能容忍任何程度的消息积压。
# 消费者和分区的关系
在Kafka里面,一个分区只能有一个消费者,但是一个消费者可以同时消费多个分区。
也就是说,如果你有N个分区,那么最多只有N个消费者,这个时候再增加消费者已经不能提高消费速率了。如果不足N个消费者,那么就会有一些消费者同时从多个分区里面拉取数据。
这种设计导致我们不能无限制地增加消费者来解决消息积压问题。反过来说,但凡没这种限制,也就没有消息积压这回事了。
# 确定分区的数量
消息积压可能是分区数量不足导致的。可能需要专业的团队,帮你创建好分区最合适的topic。
# 面试准备
- 你们公司消息队列的监控有哪些?可以利用哪些监控指标来确定消息是否积压?
- 在发现消息积压的时候,能不能利用监控的消费速率和生产速率,来推断多久以后积压的消息会被处理完毕?
- 你们公司消息积压的真实案例,包括故障原因、发现和定位过程、最终解决方案。你负责的业务使用的 topic 还有对应的分区数量。
- 如果有可能,你去问问你们消息队列团队的人是怎么计算分区数量的。
- 你的业务 topic 里面用了几个分区?你是怎么确定分区数量的?如果分区数量不够会发生什么?
- 什么情况下会发生消息积压?怎么解决消息积压的问题?
- 在异步消费的时候,如果你拉取了一批消息,还没来得及提交就宕机了会发生什么?
# 解决方案
分清楚临时性积压还是永久性积压
# 增加分区
# 创建新的topic
topic有更多的分区,前期消费老的topic,同时消费新的topic,等老的都消费完毕,可完全切换至新的topic。
# 新的分区数量
压测、单消费者的QPS、少量积压
# 优化消费者性能
- 更好的实例
- 更优雅的逻辑
# 消费者降级
# 聚合消息与批量操作
业务成本的改造
# 异步消费
# 消息丢失
批量提交 -> 数量级性能提升
# 重复消费
在消费者线程拉取了一批消息之后,如果过了一段时间还没提交就宕机了,那么会发生什么?
- 可能所有的消息都还没被处理或者正在处理。
- 部分消息被处理了,可能成功可能失败。
- 全部消息都被处理了,可能成功可能失败,还来不及提交。
保证处理消息的逻辑是幂等的就可以。
也就是同一条消息,你反复处理多少次,最终结果都是一样的。所以抓住关键词幂等来回答。
# 部分失败
要继续提交,然后继续消费下一批。
当某个工作线程失败的时候,直接重试。当工作线程重试的时候,其他工作线程也在等待,要控制重试的次数和重试的整体时间。
当然可以考虑异步重试。
更优雅的操作,失败之后,这个工作线程将这个消息再次丢回消息队列。注意表明已经重试几次了,限制只能重试三次,三次过后就不丢回去了。
# 面试思路总结
增加分区、优化消费者、聚合消息与批量操作、消费者降级、异步消息