我的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接收偏移量更改并继续执行其所做的工作(处理记录)。
谢谢。
答案 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。
临时删除kafka连接器(这将删除连接器的使用者,并
为同一使用者组(“ connect-”)创建使用者实例
让实例订阅您要重置的请求主题
进行虚拟民意测验('subscribe'会被懒惰地评估')
重置指定主题的使用者组主题偏移量
进行虚拟民意调查('seek'被懒惰地评估')提交消费者当前的偏移状态(在代理中)
重新创建kafka连接器(具有相同的连接器名称)-重新平衡后,消费者将加入该组并读取上一个提交的偏移量(从0开始)
删除临时使用者实例
如果可以使用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 实例,因此没有消费者群体参与竞争。