Consumer消费顺序。
当一个消费者消费一个partition时候,消费的数据顺序和此partition数据的生产顺序是一致的。 当一个消费者消费多个partition时候,消费者按照partition的顺序,首先消费一个partition,当消费完一个partition最新的数据后再消费其它partition中的数据。
总之:如果一个消费者消费多个partiton,只能保证消费的数据顺序在一个partition内是有序的。也就是说消费kafka中的数据只能保证消费partition内的数据是有序的,多个partition之间是无序的。
kafka可以实现以下三种语义,这三种语义是针对消费者而言的:
下面是对上面三种语义的详细分析。
at-least-once 至少一次,实现至少一次消费语义的消费者也很简单。 1. 设置enable.auto.commit为false,禁用自动提交offset。 2. 消息处理完之后手动调用consumer.commitSync()提交offset。
这种方式是在消费数据之后,手动调用函数consumer.commitSync()异步提交offset, 有可能处理多次的场景是消费者的消息处理完并输出到结果库,但是offset还没提交,这个时候消费者挂掉了,再重启的时候会重新消费并处理消息,所以至少会处理一次。
at-most-once 至多一次,至多一次消费语义是kafka消费者的默认实现。配置这种消费者最简单的方式是:
由于上面的配置,此时kafka会有一个独立的线程负责按照指定间隔提交offset。消费者的offset已经提交,但是消息还在处理中(还没有处理完),这个时候程序挂了,导致数据没有被成功处理,再重启的时候会从上次提交的offset处消费,导致上次没有被成功处理的消息就丢失了。
exactly-once 仅一次,这种语义可以保证数据只被消费处理一次。 实现仅一次语义的思路如下: 1. 将enable.auto.commit设置为false,禁用自动提交offset。 2. 使用consumer.seek(topicPartition,offset)来指定offset。 3. 在处理消息的时候,要同时保存住每个消息的offset。以原子事务的方式保存offset和处理的消息结果,这个时候相当于自己保存offset信息了,把offset和具体的数据绑定到一块,数据真正处理成功的时候才会保存offset信息。这样就可以保证数据仅被处理一次了。