Kafka处理超4000万条消息的会话级有序架构实践
在对话式AI中,同一会话的消息必须严格按序处理,否则用户先提出“伦敦机票”、再改为“巴黎”时,系统可能基于旧上下文执行错误操作。一套面向企业客户的Go语言消息层已在生产环境处理超过4000万条消息,覆盖数千个并发会话,并将发送端吞吐量提升到每秒10万条以上。
系统包含接入、自然语言理解、模型推理和消息送达四个阶段。由于Kafka只能保证单分区内有序,而一个分区会交错承载多个会话,架构采用两层工作模型:分发协程按会话ID做一致性哈希,将同一会话固定路由到同一处理单元;每个活跃会话再由独立goroutine逐条处理,不同会话可以并行。
早期的固定协程池会因某个会话重试而阻塞其他会话,并造成内存队列增长。改进后的会话goroutine按需创建、闲置回收,每次只处理一条消息。相比为每个会话建立Kafka分区,这种方式避免分区数量随会话数膨胀,也保留了较高并行度。
重试在原会话goroutine内完成。可恢复错误采用带随机抖动的指数退避,后续消息留在队列中,不能越过失败消息;无效等不可恢复消息则直接进入死信队列(DLQ)。因此无需额外重试通道或复杂状态机,能够保持严格顺序。
并发会话完成顺序不同,偏移量不能直接提交到最新完成位置。系统按分区跟踪处理中和已完成偏移量,只把提交水位线推进到最高连续完成点。例如104先完成而102未完成时,不能提交104。崩溃后可能重放消息,系统使用稳定事件ID去重,但最终效果仍依赖下游幂等性,并不等于恰好一次执行。
生产环境还需配套再均衡、背压、卡住偏移量检测、链路追踪和优雅关停。再均衡时停止接收新记录,每50毫秒检查任务排空;通道满载时暂停拉取,并按分区缓冲已拉取记录,每秒检查恢复条件。处理超时的偏移量可记录到DLQ后推进分区,但这是以完整性换取可用性的最后手段。
生产端同样使用一致性哈希和FIFO发送,失败消息进入DLQ,关闭前先刷新待发送数据。消费者关停时停止拉取、完成会话任务并提交最终连续水位线;未提交记录会在重启后重放。团队先通过合成故障测试顺序、重试、吞吐和延迟,再进行生产规模验证,基准环境为AWS EC2 c5.2xlarge,配置8个vCPU和16GB内存。
本文基于公开渠道信息整理,内容可能存在不准确或遗漏之处,不代表本站立场,如内容涉及侵权或错误,请联系我们处理。
阅读原文