为了解决上述两个问题,Kafka进行了重新的设计,将分区分配的工作放到了消费者这一端进行,而Consumer Group管理的工作则依然由GroupCoordinator处理。
代码提交可参考https://issues.apache.org/jira/browse/KAFKA-2464
https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Client-side+Assignment+Proposal
重新设计后的协议在上一版本的协议上进行了修改,将JoinGroupRequest的处理过程拆分成了两个阶段,分别是Join Group阶段和Synchronizing Group State阶段。
当消费者找到管理当前Group的GroupCoordinator后,就会进入Join Group阶段,Consumer首先向GroupCoordinator发送JoinGroupRequest请求,其中包含消费者的相关信息。
服务端的GroupCoordinator收到JoinGroupRequest后,会暂存消息,收集到全部消费者后,根据JoinGroupRequest中的信息来确定Consumer Group中可用的消费者,从中选取一个消费者成为Group Leader,还会选取使用的分区分配策略,最后将这些信息封装成JoinGroupResponse返回给消费者。
虽然每个消费者都会收到JoinGroupResponse,但是只有Group leader收到的JoinGroupResponse中封装了素有的消费者信息。
当消费者确定自己时Group Leader后,会根据消费者的信息以及选定的分区分配策略进行分区分配。
在Synchronizing Group State阶段,每个消费者会发送SyncGroupRequest到GroupCoordinator,但只有Group Leader的SyncGroupRequest请求包含了分区的分配结果,GroupCoordinator根据GroupLeader的分区分配结果,形成SyncGroupResponse返回给所有的Consumer。
消费者收到SyncGroupResponse后进行解析,即可获取分配给自身的分区。