3.Kafka消费者
拓扑结构
消费者群组
Kafka的消费组从属于消费者群组。一个群组里面的消费者订阅的是同一个主题(topic),每个消费者接收主题一部分分区的消息。
Kafka消费者的横向伸缩:
为每一个需要获取一个或者多个主题全部消息的应用程序创建一个消费者群组,然后往群组里添加消费者来伸缩读取能力和处理能力,群组里面的每个消费者只处理一部分消息。
对于同一个消费者群组,一个消息只能被组内的一个consumer消费,因此:
-
consumer数量大于partition数量,则有部分consumer会闲置,不会接收到任何消息
-
consumer数量小于partition数量,则有部分consumer会接收到多个partition的消息
偏移量
消费者往_consumer_offset的特殊topic发送消息,消息里包含每个分区的偏移量。如果消费者发生崩溃或者有新的消费者加入群组,就会触发再均衡,完成再均衡之后,每个消费者可能分配到新的分区,而不是之前处理的那个。为了能够继续之前的工作,消费者需要读取每个分区最后一次提交的偏移量,然后从偏移量指定的地方继续处理。
如果提交的偏移量小于客户端处理的最后一个消息的偏移量,那么处于两个偏移量之间的消息就会被重复处理;如果提交的偏移量大于客户端最后处理的一个消息的偏移量,那么处于两个偏移量之间的消息就会丢失。
偏移量提交的方式:
-
自动提交
最简单的提交方式是让消费者自动提交偏移量。如果enable.auto.commit被设为true,那么每经过提交时间间隔,消费者会自动把从poll( )方法接收到的最大偏移量提交上去,提交时间间隔由auto.commit.interval.ms控制。
-
手动提交
把enable.auto.commit设为false,让应用程序决定何时提交偏移量。提交偏移量的方式包括同步、异步两种方式:
-
commitSync()
commitSync()将会提交由poll()返回的最新偏移量,提交成功后马上返回,如果提交失败会抛出异常。只要没有发生不可恢复的错误,commitSync()方法会一直尝试直至提交成功。
-
commitAsync()
commitAsync()会异步提交由poll()返回的最新偏移量,但是commitAsync()不会进行重试,因为在它收到服务器响应的时候,可能有一个更大的偏移量已经提交成功。
-
针对实际的情况,一般会组合使用commitSync()、commitAsync()。在处理过程中使用commitSync(),在最后consumer关闭前,使用commitSync()同步提交。
另外,也可以提交特定的偏移量,在调用commitSync()、commitAsync()方法时,传进去希望提交的分区和偏移量的map。
分区再均衡(Reblance)
群组里的消费者共同读取主题的分区。一个新的消费者加入群组时,它读取的是原本由其他消费者读取的消息。当一个消费者被关闭或者发生崩溃时,它离开群组,原本由它读取的分区将由群组里的其他消费者来读取。在主题发生变化时,比如添加了新的分区,会发生分区重分配。
分区的所有权从一个消费者转移到另一消费者,这样的行为也就是再均衡。再均衡为消费者群组带来了高可用性和伸缩性。但是在再均衡期间,消费者无法读取消息,造成整个群组一小段时间内的不可用。
消费者通过向群组协调器发送心跳来维持它们和群组的从属关系以及对分区的所有权关系。只要消费者以正常的时间间隔发送心跳,就被认为是活跃的。消费者会在轮询消息或提交偏移量时发送心跳。如果消费者停止发送心跳的时间足够长,会话就会过期,群组协调器认为它已经死亡,就会触发一次再均衡。
//TDOO 补充Reblance算法