消费者和消费组
-
消费者:负责订阅kafka中的主题,并且从主题拉取消息。通过group.id来配置消费组,消费者是一个逻辑的概念,将所属的消费者归为一类。 -
消费组:每个消费者都有一个对应的消费组,消息发布到主题后,只会投递给订阅它的每个消费组中的一个消费者。消费者不是逻辑上的概念,是实际的应用实例。 -
分区:每个分区只能被一个消费组中一个消费者所消费,为了增加消费能力可以增加消费者,如果分区固定了,需考虑分区个数和消费者个数的关系,消费者个数不应大于分区个数,这样消费者会分配不到分区而无法消费任何消息。
消息的投递模式
kafka支持两种消息投递模式:点对点,发布/订阅 。
- 如果所有的消费组属于同一个消费组,那么所有的消息都会被均衡第投递给每一个消费者,即每条消息只会被一个消费者处理,这就相当于点对点模式的应用
- 如果所以的消费者都隶属于不同的消费组,那么所有的消息都会广播给所有的消费者,即每条消息都会被所有的消费者处理,这就相当于发布/订阅的应用。
消息消费
消息消费有两种模式:推模式和拉模式,kafka的消息时基于拉模式的
- 推模式:服务端主动将消息推送给消费者
- 拉模式:消费者主动向服务端发请求拉取消息
位移提交
-
对于kafka中的分区而言,它的每条消息都有唯一的offset(偏移量、位移),用来表示消息在分区中对应的位置。 -
每次调用poll获取消息时,返回的是没有被消费的消息,要坐到这一点需要记录上次消费消息的唯一,这个消费位移需要做持久化保存,老版本的消费者客户端是保存在zookeeper里面,新版本的消费者客户端是保存在kafka内部的主题_cosumer_offset中,把消费位移储存起来的动作称为位移提交。 -
kafka中默认的消费位移的提交方式是自动提交,这个消费者客户端参数enable.auto.comit配置,默认为true,提交为周期提交,周期时间为auto.commit.interval.ms配置,默认是5秒 -
自动提交位移的坏处:容易造成重复消费和消息丢失 -
重复消费:消费者刚提交了消费位移,在下次消费提交之前又消费了一次消息,这样客户端的消费位移未更新,会消费到之前消费过的重复消息。 -
消息丢失:如果线程1从客户端拉取(n+10)个消息缓存在本地,此时消费端提交了(n+8)的位移,此时线程2消费到了(n+3),如果此时线程2挂了,则(n+3) 到(n+8)的消息会丢失。 kafka在正常的情况下不会发生消息重复消费和消息丢失,如果为了避免可以采用手动提交的方式。手动提交分为同步提交和异步提交。
指定位移消费
-
当一个新的消费组建立或者消费组内的一个新的消费者订阅了一个新的主题,它根本没有可以查找的消费位移。此时会根据消费者客户端参数auto.offset.reset的配置来决定从何处开始进行消费,默认为"latest" -
latest:标识从分区末尾开始消费消息 -
earliest:从起始位置0开始消费 -
none:找不到消费位移的时候会报出异常NoOffsetForPartitionException 消费位移除了指定末尾和开始,也可以指定值(直接指定数值或者根据时间获取某个时间段的位移值),消费位移也可以存在DB中。
再均衡
- 再均衡是指分区的所属权从一个消费者转移到另一个消费者的行为,在再均衡期间,消费组内的消息无法读取消息,消费组不可用。当一个分区被重新分配给另一个消费者,当前消费者的一部分消息还未消费完,以及消费位移还未提交,另一个消费者会出现重复消费的现象。
可以在调用subscribe时指定ConsumerRebalanceListener均衡监听器,通过内置方法提交或者保存消费位移,避免消息丢失或者重复消费。
|