消费组组(Consumer group)可以说是kafka很有亮点的一个设计。传统的消息引擎处理模型主要有两种,队列模型,和发布-订阅模型。
队列模型:早期消息处理引擎就是按照队列模型设计的,所谓队列模型,跟队列数据结构类似,生产者产生消息,就是入队,消费者接收消息就是出队,并删除队列中数据,消息只能被消费一次。但这种模型有一个问题,那就是只能由一个消费者消费,无法直接让多个消费者消费数据。基于这个缺陷,后面又演化出发布-订阅模型。
发布-订阅模型:发布订阅模型中,多了一个主题。消费者会预先订阅主题,生产者写入消息到主题中,只有订阅了该主题的消费者才能获取到消息。这样一来就可以让多个消费者消费数据。
以往的消息处理引擎大多只支持其中一种模型,但借助kafka的消费者组机制,可以同时实现这两种模型。同时还能够对消费组进行动态扩容,让消费变得易于伸缩。
这篇我们先介绍下消费者组,然后主要讨论kafka著名的重平衡机制。
kafka消费者组所谓消费者组,那自然是由消费者组成的,组内可以有一个或多个消费者实例,而这些消费者实例共享一个id,称为group id。对了,默认创建消费者的group id是在KAFKA_HOME/conf/consumer.properties文件中定义的,打开就能看到。默认的group id值是test-consumer-group。
消费者组内的所有成员一起订阅某个主题的所有分区,注意一个消费者组中,每一个分区只能由组内的一消费者订阅。
看看下面这张图,这是kakfa官网上给出的说明图。
这张图应该很好的说明了消费者组,我们从上到下解释一下,kafka cluster中有两台broker服务器,每一台都有两个分区,这四个分区都是同一个topic下的。下左的消费者组A,组内有两个消费者,每个消费者负责两个分区的消费,而右边的消费者组B有四个消费者,每个负责消费一个分区。
当消费者组中只有一个消费者的时候,就是消息队列模型,不然就是发布-订阅模型,并且易于伸缩。
消费者组内消费者数量上面那张图,仔细推敲一下就会发现,图中其实已经有一些既定的事实,比如消费者组内消费者小于或等于分区数,以及topic分区数刚好是消费者组内成员数的倍数。
那么如果消费者组内成员数超过分区数会怎样呢?比如有4个分区,但消费者组内有6个消费者,这时候有2个消费者不会分配分区,它会一直空闲。
而如果消费者不是分区的倍数,比如topic内有4个分区,而消费者组内有三个消费者,那怎么办呢?这时候只会有两个消费者分别被分配两个分区,第三个消费者同样空闲。
所以,消费者组内的消费者数量最好是与分区数持平,再不济,最好也是要是分区数的数量成比例。
查看集群中的消费者组这里顺便说下如何查看消费者组及组内消费情况,可以使用ConsumerGroupCommand命令工具,来查看具体的kafka消费者组。注意,这里都是以最新版的kafka版本,也就是2.+版本。
可以使用如下命令列出当前集群中的kafka组信息。
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list test-consumer-group具体到某个组的消费者情况,可以使用下面这条命令工具:
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID topic3 0 241019 395308 154289 consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1 consumer2 topic2 1 520678 803288 282610 consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1 consumer2 topic3 1 241018 398817 157799 consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1 consumer2 topic1 0 854144 855809 1665 consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1 consumer1 topic2 0 460537 803290 342753 consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1 consumer1 topic3 2 243655 398812 155157 consumer4-117fe4d3-c6c1-4178-8ee9-eb4a3954bee0 /127.0.0.1 consumer4 重平衡(Rebalance)说完消费者组,再来说说与消费者组息息相关的重平衡机制。重平衡可以说是kafka为人诟病最多的一个点了。
重平衡其实就是一个协议,它规定了如何让消费者组下的所有消费者来分配topic中的每一个分区。比如一个topic有100个分区,一个消费者组内有20个消费者,在协调者的控制下让组内每一个消费者分配到5个分区,这个分配的过程就是重平衡。
重平衡的触发条件主要有三个:
消费者组内成员发生变更,这个变更包括了增加和减少消费者。注意这里的减少有很大的可能是被动的,就是某个消费者崩溃退出了
主题的分区数发生变更,kafka目前只支持增加分区,当增加的时候就会触发重平衡
订阅的主题发生变化,当消费者组使用正则表达式订阅主题,而恰好又新建了对应的主题,就会触发重平衡