offset存储在哪
关于偏移量offset默认存储在什么地方,请看这Consumer的offset保存在哪里
当然也可以自己主动设置在zookeeper,redis等里,
下面说的更像为什么用,或者说怎么用的逻辑来自offset存储在其他地方
- 如果消费的结果存储在关系数据库中,存储在数据库的offset,让提交结果和offset在单个事务中。这样,事物成功,则offset存储和更新。如果offset没有存储,那么偏移量也不会被更新。
- 如果offset和消费结果存储在本地仓库。例如,可以通过订阅一个指定的分区并将offset和索引数据一起存储来构建一个搜索索引。如果这是以原子的方式做的,常见的可能是,即使崩溃引起未同步的数据丢失。索引程序从它确保没有更新丢失的地方恢复,而仅仅丢失最近更新的消息。
每个消息都有自己的offset,所以要管理自己的偏移,你只需要做到以下几点:
- 配置 enable.auto.commit=false
- 使用提供的 ConsumerRecord 来保存你的位置。
- 在重启时用 seek(TopicPartition, long offset) 恢复消费者的位置。
当分区分配也是手动完成的(像上文搜索索引的情况),这种类型的使用是最简单的。 如果分区分配是自动完成的,需要特别小心处理分区分配变更的情况。可以通过调用subscribe(Collection,ConsumerRebalanceListener)
和subscribe(Pattern,ConsumerRebalanceListener)
中提供的ConsumerRebalanceListener实例来完成的。
例如,当分区向消费者获取时,消费者将通过实现ConsumerRebalanceListener.onPartitionsRevoked(Collection)
来给这些分区提交它们offset。当分区分配给消费者时,消费者通过ConsumerRebalanceListener.onPartitionsAssigned(Collection)
为新的分区正确地将消费者初始化到该位置。
ConsumerRebalanceListener的另一个常见用法是清除应用已移动到其他位置的分区的缓存。
订阅指定的分区
上面包括以前的例子都是消费者订阅主题就好,分区什么的不用管,因为kafka给我们平分分区,但是可能有时需要我们自己主动的去订阅指定的分区
我看人家的例子挺好的,就复制过来了,有想看的可以去订阅指定的分区看看,在页面的下半部分
- 如果这个消费者进程与该分区保存了某种本地状态(如本地磁盘的键值存储),则它应该只能获取这个分区的消息。
- 如果消费者进程本身具有高可用性,并且如果它失败,会自动重新启动(可能使用集群管理框架如YARN,Mesos,或者AWS设施,或作为一个流处理框架的一部分)。 在这种情况下,不需要Kafka检测故障,不需要重新分配分区,因为消费者进程将在另一台机器上重新启动。
怎么实现呢?
consumer.subscribe(Arrays.asList("my-replicated-topic"));//主题
//上面这行命令换成下面这四句
String topic = "foo";
TopicPartition partition0 = new TopicPartition(topic, 0);//主题,分区
TopicPartition partition1 = new TopicPartition(topic, 1);//主题,分区
consumer.assign(Arrays.asList(partition0, partition1));
注意:手动分配分区(即,assgin)和动态分区分配的订阅topic模式(即,subcribe)不能混合使用。
控制消费的位置
大多数情况下,消费者只是简单的从头到尾的消费消息,周期性的提交位置(自动或手动)。kafka也支持消费者去手动的控制消费的位置,可以消费之前的消息也可以跳过最近的消息。
有几种情况,手动控制消费者的位置可能是有用的。
- 一种场景是对于时间敏感的消费者处理程序,对足够落后的消费者,直接跳过,从最近的消费开始消费。
- 另一个使用场景是本地状态存储系统。在这样的系统中,消费者将要在启动时初始化它的位置(无论本地存储是否包含)。同样 如果本地状态已被破坏(假设因为磁盘丢失),则可以通过重新消费所有数据并重新创建状态(假设kafka保留了足够的历史)在新的机器上重新创建。
kafka使用seek(TopicPartition, long)
指定新的消费位置。
用于查找服务器保留的最早和最新的offset的特殊的方法也可用(seekToBeginning(Collection)
和 seekToEnd(Collection)
)。
消费者流量控制
如果消费者分配了多个分区,并同时消费所有的分区,这些分区具有相同的优先级。
在一些情况下,消费者需要首先消费一些指定的分区,当指定的分区有少量或者已经没有可消费的数据时,则开始消费其他分区。
例如:流处理,当处理器从2个topic获取消息并把这两个topic的消息合并,当其中一个topic长时间落后另一个,则暂停消费,以便落后的赶上来。
kafka支持动态控制消费流量,分别在future的poll(long)中使用pause(Collection) 和 resume(Collection) 来暂停消费指定分配的分区,重新开始消费指定暂停的分区。