最近手上的项目需要拉去kafka的消息进行消费,不过以前没使用过kafka,这两天安装及摸索使用了kafka,对于在一个服务里开启多个kafka的消费者来提高消费速度的问题上,目前自己已摸索清楚并测试通过,故记录下。
一. 项目场景
在分布式的情景下,有多个应用服务将消息推送到kafka的topic里,需要开发一个应用服务去拉去kafka的消息并进行消费,由于消息的生产速度很快,如果只开一个消费者去进行消费的话,会导致大量消息堆积于kafka,所以需要进行提升消费者的速度。
二. 提升消费者速度的手段
- 开启多个kafka的消费者一起进行消费
- 对每个kafka的消费者又开一个业务处理池
- 其他(逻辑优化、SQL优化等)
第二点和第三点已经做了优化了,所以还想从第一点进行优化,以下就对第一点的优化做一个详细描述。
三. Kafka的基本知识
- Broker(代理者):Kafka集群中的机器/服务被成为broker, 是一个物理概念。
- Topic(主题):维护Kafka上的消息类型被称为Topic,是一个逻辑概念。
- Partition(分区):具体维护Kafka上的消息数据的最小单位,一个Topic可以包含多个分区;Partition特性:ordered & immutable。(在数据的产生和消费过程中,不需要关注数据具体存储的Partition在那个Broker上,只需要指定Topic即可,由Kafka负责将数据和对应的Partition关联上)
- Producer(生产者):负责将数据发送到Kafka对应Topic的进程。
- Consumer(消费者):负责从对应Topic获取数据的进程。
- Consumer Group(消费者组):每个consumer都属于一个特定的group组,一个group组可以包含多个consumer,但一个组中只会有一个consumer消费数据。
- Message(消息):传递的数据对象,主要由四部分构成:offset(偏移量)、key、value、timestamp(插入时间); 其中offset和timestamp在kafka集群中产生,key/value在producer发送数据的时候产生。
一个topic可以配置多个partition,produce发送的消息分发到不同的partition中,consumer接受数据的时候是按照group来接受,kafka确保每个partition只能同一个group中的一个consumer消费,如果想要重复消费,那么需要其他的组来消费。
四. 走过的那些弯路(也是为了测试)
- case 1:在一个应用服务里创建1个消费者,然后把该应用服务放2台机器去跑,最终也是只有一个服务能收到消息,只有关闭其一之后,另一个服务才能收到消息,这不是我所期望的。
- case 2:在一个应用服务里创建3个消费者,每个消费者的GroupID都不一样,最终是这3个消费者都接收到了数据,这不是我所期望的。
- case 3:在一个应用服务里创建3个消费者,3个消费者的GroupID都是一样的,最终是只有一个消费者消费了消息,另2个消费者一直消费不到消息。
- case 4:修改kafka的配置文件(vim /usr/local/etc/kafka/server.properties),将num.partitions=1修改为num.partitions=5,并重启kafka,由于默认kafka的配置是一个topic只有一个partition,而kafka确保每个partition只能同一个group中的一个consumer消费,当生产者推送消息时由于会负载均衡的分配到每个partition(目前partition数量为5),所以当每个partition都有数据时,应用服务在这种情况下一次最多可以消费5个数据,这样就提升了消费速度。这才是我想期望的。
五. 自己写的项目