kafka 作为一种高吞吐量的分布式发布订阅消息系统,在业务系统中被广泛的使用。
如果问你,如何提高 kafka 队列中的消息消费速度呢? 答案很简单,topic 多分几个分片,然后使用消费者组(Consumer Group)去消费 topic 即可。
如果加个条件,对同一个对象的操作请求必须要严格按照顺序进行处理呢? 答案也不难,topic 分片之后,生产者定制分发策略,保证同一对象的操作请求都分发到同一个分片中,这样每个消费者就都是在按照顺序消费各自分片中的数据啦~
如果再加上一些条件:
-
这个消费者消费速度极慢、慢到需要 100ms 才能处理完一条消息,即使 topic 分 100 片也不满足不了要求;
-
每个对象的操作请求数量存在严重倾斜的现象,有的分片消息数量很大,有的分片消息量很少,可能有的分片一直积压、有的分片却很闲;
-
请求操作很重要,需要确保每条请求都被可靠消费,要保证事务最终一致性;
-
数十年的老系统,业务错综复杂,项目方不允许涉及业务逻辑以及整体架构的大改...
当上述各种条件叠加到一起,要求将消费性能明显提升,如果是你,会如何破局呢?
前段时间,应业务部门的要求,给他们的一个线上历史系统做个并发性能提升的方案,就遇到了上述各种要求叠加在一起的棘手情况。
先简单说下遇到的业务场景:
一个互动类的论坛的帖子评论处理场景,要求每个帖子的评论请求操作都必须要严格遵循一定的顺序(比如可能会有评论删除、引用评论、回复评论等操作,所以请求顺序必须要严格按照顺序处理),帖子评论的操作请求发送到 kafka 里面,然后评论服务消费 kafka 处理各个请求,这个评论消费者服务消费太慢,需要提升下并发效率。
增加分片与消费者数量
正式开始着手去整改优化。
首先是常规调整:根据 kafka 自身的机制,将 topic 进行分片调整,拆分为 N 个分片,然后增设消费者组,在消费者组内部署与分片数相等的消费者服务节点,这样每个消费者可以处理一个分片,这样整个评论的消费性能就会提升 N 倍。
那么,这里为什么要强调消费者组里的服务节点数要等于 topic 分片数呢?这里提一下 kafka 中 Consumer Group 中消费者数量与 t