是否可以在kafka连接器中为kafka消费者组的主题重置偏移量?

时间:2019-05-01 09:29:51

标签: apache-kafka kafka-consumer-api apache-kafka-connect

我的kafka接收器连接器读取多个主题(配置了10个任务),并处理所有主题中的300多个记录。根据每个记录中保存的信息,连接器可以执行某些操作。

以下是触发记录中的key:value对的示例:

"REPROCESS":"my-topic-1"

在读取该记录后,我将需要将主题“ my-topic-1”在每个分区中的偏移量重置为0。

我已经在很多地方读到了推荐的方法,即创建一个新的KafkaConsumer,订阅该主题的分区,然后调用subscribe(...)方法。例如,

public class MyTask extends SinkTask { . . . @Override public void put(Collection<SinkRecord> records) { records.forEach(record -> { if (record.key().toString().equals("REPROCESS")) { reprocessTopicRecords(record); } else { // do something else } }); } private void reprocessTopicRecords(SinkRecord record) { KafkaConsumer<JsonNode, JsonNode> reprocessorConsumer = new KafkaConsumer<>(reprocessorProps, deserializer, deserializer); reprocessorConsumer.subscribe(Arrays.asList(record.value().toString()), new ConsumerRebalanceListener() { public void onPartitionsRevoked(Collection<TopicPartition> partitions) {} public void onPartitionsAssigned(Collection<TopicPartition> partitions) { // do offset reset here } } ); } }

但是,上述策略不适用于我的情况,因为: 1.这取决于发生的小组重新平衡(并非总是发生) 2.传递给onPartitionsAssigned方法的“分区”是动态分配的分区,这意味着它们只是整个分区集合的一个子集,需要重置其偏移量。例如,此SinkTask将仅分配8个分区中的2个,这些分区保存着“ my-topic-1”的记录。

我也研究过使用assign(),但这与SinkConnector / SinkTask实现中的分布式使用者模型(使用者组)不兼容。

我知道kafka命令行工具kafka-consumer-groups可以完全满足我的要求(我认为): https://gist.github.com/marwei/cd40657c481f94ebe273ecc16601674b

总而言之,我想使用Java API重置给定主题的所有分区的偏移量,并让Sink Connector接收偏移量更改并继续执行其所做的工作(处理记录)。

谢谢。

3 个答案:

答案 0 :(得分:0)

您正在寻找seek方法。要么偏移

consumer.seek(new TopicPartition("topic-name", partition), offset);

seekToBeginning

但是,我觉得您将与Connect Sink API的消费者群体竞争。换句话说,假设您使用一个单独的组ID设置使用者,那么实际上,您在这里使用源主题中的两次记录,一次是通过Connect,然后是您自己的使用者实例。

除非您也明确寻求Connect自己的使用者实例(未公开),否则您将进入一种奇怪的状态。例如,您的任务仅在该主题的新记录上执行,尽管事实是您自己的使用者正在查看旧的偏移量,或者您在处理旧事件时仍会得到新的事件

此外,由于保留策略(例如过期记录),最终您可能会在主题的最开始处遇到重新处理事件,例如,导致您的消费者根本无法进步,并通过寻找开始位置来不断重新平衡其组< / p>

答案 1 :(得分:0)

通过使用一系列Confluent的kafka-rest-proxy API:https://docs.confluent.io/current/kafka-rest/api.html

,我能够为kafka connect消费群体实现重置偏移量

此实现不再需要原始帖子中描述的“触发记录”方法,并且完全基于Rest API。

  1. 临时删除kafka连接器(这将删除连接器的使用者,并

  2. 为同一使用者组(“ connect-”)创建使用者实例

  3. 让实例订阅您要重置的请求主题

  4. 进行虚拟民意测验('subscribe'会被懒惰地评估')

  5. 重置指定主题的使用者组主题偏移量

  6. 进行虚拟民意调查('seek'被懒惰地评估')提交消费者当前的偏移状态(在代理中)

  7. 重新创建kafka连接器(具有相同的连接器名称)-重新平衡后,消费者将加入该组并读取上一个提交的偏移量(从0开始)

  8. 删除临时使用者实例

如果可以使用CLI,则步骤2-6可以替换为:

kafka-consumer-groups --bootstrap-server <kafkahost:port> --group <group_id> --topic <topic_name> --reset-offsets --to-earliest --execute

对于那些尝试通过本机Java API在kafka连接器代码中执行此操作的人,您很不走运:-(

答案 2 :(得分:0)

我们不得不做一个非常相似的偏移重置练习。

KafkaConsumer.seek()KafkaConsumer.commitSync() 结合使用效果很好。

如果您要处理大量主题和分区 (javadoc),还有一个值得一提的选项:

AdminClient.alterConsumerGroupOffsets(
  String groupId, 
  Map<TopicPartition,OffsetAndMetadata> offsets
)

我们很幸运,因为我们有幸暂时停止了 Kafka Connect 实例,因此没有消费者群体参与竞争。