Apache kafka 是否可以重置卡夫卡连接器中卡夫卡使用者组的主题偏移?

Apache kafka 是否可以重置卡夫卡连接器中卡夫卡使用者组的主题偏移?,apache-kafka,kafka-consumer-api,apache-kafka-connect,Apache Kafka,Kafka Consumer Api,Apache Kafka Connect,我的kafka接收器连接器从多个主题(配置了10个任务)读取数据,并处理来自所有主题的300多条记录。根据每个记录中保存的信息,连接器可以执行某些操作 以下是触发器记录中的key:value对示例: “重新处理”:“my-topic-1” 读取此记录后,我需要将每个分区中的主题“my-topic-1”的偏移量重置为0 我在很多地方都读到过,建议创建一个新的KafkaConsumer,订阅主题的分区,然后调用subscribe(…)方法。比如说, public class MyTask exten

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

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

“重新处理”:“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
                }
            }
        );
    }
}
公共类MyTask扩展了MyTask{
@凌驾
公众认股权证(收款记录){
记录。forEach(记录->{
if(record.key().toString().equals(“重新处理”)){
再处理主题记录(记录);
}否则{
//做点别的
}
});
}
私人作废的TopicRecords(SinkRecord记录){
卡夫卡消费者再加工消费者=
新KafkaConsumer(再处理程序、反序列化程序、反序列化程序);
reprocessorConsumer.subscribe(Arrays.asList(record.value().toString()),
新的ConsumerBalanceListener(){
公共void onPartitionsRevoked(集合分区){}
公共void onPartitionsAssigned(集合分区){
//在这里重置偏移量吗
}
}
);
}
}
但是,上述策略不适用于我的案例,因为: 1.这取决于发生的团队再平衡(并不总是发生) 2. '传递给
onPartitionsAssigned
方法的分区是动态分配的分区,这意味着这些分区只是需要重置其偏移量的完整分区集的子集。例如,在保存“my-topic-1”记录的8个分区中,只有2个分区将分配此任务

我还研究了如何使用
assign()
,但这与SinkConnector/SinkTask实现中的分布式消费者模型(消费者组)不兼容

我知道kafka命令行工具
kafka消费群体
可以完全满足我的需求(我认为):

总之,我想使用JavaAPI重置给定主题的所有分区的偏移量,并让接收器连接器获取偏移量更改并继续执行它一直在做的事情(处理记录)


提前感谢。

您正在寻找seek方法。要么到一个偏移量

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

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

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


此外,由于保留策略的原因,例如旧记录过期,最终您可能会在主题的最开始处收到一个重新处理事件,使您的消费者毫无进展,并通过从头开始不断重新平衡其组

我能够通过使用Confluent的一系列kafka rest代理API重置kafka connect消费者组的偏移:

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

  • 暂时删除kafka连接器(这将删除连接器的使用者和)

  • 为同一消费者组创建消费者实例(“连接-”)

  • 让实例订阅要重置的请求主题

  • 执行虚拟轮询(“订阅”是惰性计算的)

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

  • 执行虚拟轮询(“seek”被惰性地计算)为使用者提交当前偏移量状态(在代理中)

  • 重新创建kafka连接器(具有相同的连接器名称)-重新平衡后,使用者将加入组并读取最后提交的偏移量(从0开始)

  • 删除临时使用者实例

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

    kafka消费群体--引导服务器--群体--主题--重置偏移量--最早--执行


    对于那些试图通过本机Java API在kafka连接器代码中实现这一点的人来说,你运气不好:-(

    我们必须做一个非常类似的偏移重置练习

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

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

    AdminClient.AlterConsumerGroupOffset(
    字符串groupId,
    地图偏移
    )
    

    我们很幸运,因为我们有足够的时间停止Kafka Connect实例,因此没有消费者群体竞争。

    感谢您的解释-您所说的似乎与本文的内容一致:我必须尝试使用新创建的加入sam的Kafka消费者来寻找/提交补偿e Connect consumer group(组id通常为“Connect-2”问题:1)为什么要重新处理主题?2)为什么不使用freshNewGroupId?1)以使用数据、转换数据和POST/PU的接收器连接器为例