Kafka系列(30)怎么重设消费组位移

为什么要重设消费组位移

  Kafka的消费者读取消息是可以重演的。

  RabbitMQ ActiveMQ 这样传统的消息中间件,处理和响应消息的方式,一旦消息被成功处理就会从Broker上删除

   kafka是基于日志结构的消息引擎,消费者在消费消息时,仅仅是从磁盘上读取数据而已,只是读的操作,因此消费者不会删除消息数据。同时,由于位移数据是由消费者控制的,因此它能够很容易地修改位移的值,实现重复消费历史数据的功能

  选择Kafka   如果你的场景时较高的通吐量,每条消息的处理时间都很短,同时很在意消息的顺序

 

 

重设位移策略

   1位移维度   根据位移值重设,直接吧消费者的位移值重设成我们给定的位移值

   2时间维度   给定一个时间维度,让消费者把位移调整成大于该时间的最小位移;也可以给出一段时间比如30分钟前,然后让消费者直接将位移调回到30分钟之前的位移值

Kafka系列(30)怎么重设消费组位移_第1张图片

Current策略表示将位移调整到消费者当前提交的最新位移。

    你修改了消费者程序代码,并重启了消费者,结果发现代码有问题,需要回滚之前的代码变更,同时也要把位移重设到消费者重启时的位置。

Specified-Offset   消费者程序在处理某条错误消息时,可以手动跳过此消息。在实际使用过程中,可能会出现corrupted消息无法被消费的情形,此时情绪会抛出异常,无法继续工作

Shift-By-N策略制定位移的相对数值  可以向前跳也可以向后跳

DateTime允许制定一个时间 然后将位移重置到该时间之后的最早位移处。常见的使用场景是,你想重新消费昨天的而数据,可以使用该策略将位移移到昨天0点

Duration策略是指给定的时间间隔

   如果想将位移调回到15分钟之前,那么指定PT0H15M0S

 

重设消费者组位移的方式有两种

   通过消费者API来实现

      void seek(TopicPartition partition, long offset);
      void seek(TopicPartition partition, OffsetAndMetadata offsetAndMetadata);

      调整多个主题分区
      void seekToBeginning(Collection partitions);
      void seekToEnd(Collection partitions);

   Earliest策略

Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, groupID);
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, brokerList);

String topic = "test";  // 要重设位移的 Kafka 主题 
try (final KafkaConsumer consumer = 
    new KafkaConsumer<>(consumerProperties)) {
         consumer.subscribe(Collections.singleton(topic));
         consumer.poll(0);
         consumer.seekToBeginning(
    consumer.partitionsFor(topic).stream().map(partitionInfo ->          
    new TopicPartition(topic, partitionInfo.partition()))
    .collect(Collectors.toList()));

   1创建的消费者程序,禁止自动提交位移

Latest 策略

consumer.seekToEnd(
    consumer.partitionsFor(topic).stream().map(partitionInfo ->          
    new TopicPartition(topic, partitionInfo.partition()))
    .collect(Collectors.toList()));

Current策略

consumer.partitionsFor(topic).stream().map(info -> 
    new TopicPartition(topic, info.partition()))
    .forEach(tp -> {
    long committedOffset = consumer.committed(tp).offset();
    consumer.seek(tp, committedOffset);
});

 

Specified-Offset策略

long targetOffset = 1234L;
for (PartitionInfo info : consumer.partitionsFor(topic)) {
    TopicPartition tp = new TopicPartition(topic, info.partition());
    consumer.seek(tp, targetOffset);
}

Shift-By-N策略

for (PartitionInfo info : consumer.partitionsFor(topic)) {
         TopicPartition tp = new TopicPartition(topic, info.partition());
    // 假设向前跳 123 条消息
         long targetOffset = consumer.committed(tp).offset() + 123L; 
         consumer.seek(tp, targetOffset);
}
 

DateTime策略

long ts = LocalDateTime.of(
    2019, 6, 20, 20, 0).toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
Map timeToSearch = 
         consumer.partitionsFor(topic).stream().map(info -> 
    new TopicPartition(topic, info.partition()))
    .collect(Collectors.toMap(Function.identity(), tp -> ts));

for (Map.Entry entry : 
    consumer.offsetsForTimes(timeToSearch).entrySet()) {
consumer.seek(entry.getKey(), entry.getValue().offset());
}
 

Duration策略代码

Map timeToSearch = consumer.partitionsFor(topic).stream()
         .map(info -> new TopicPartition(topic, info.partition()))
         .collect(Collectors.toMap(Function.identity(), tp -> System.currentTimeMillis() - 30 * 1000  * 60));

for (Map.Entry entry : 
         consumer.offsetsForTimes(timeToSearch).entrySet()) {
         consumer.seek(entry.getKey(), entry.getValue().offset());
}
 

   通过Kafka-consumer-groups命令行脚本来实现

Earliest 策略直接指定–to-earliest

bin/kafka-consumer-groups.sh --bootstrap-server kafka-host:port --group test-group --reset-offsets --all-topics --to-earliest –execute

Latest 策略直接指定–to-latest。

bin/kafka-consumer-groups.sh --bootstrap-server kafka-host:port --group test-group --reset-offsets --all-topics --to-latest --execute

Current 策略直接指定–to-current。

bin/kafka-consumer-groups.sh --bootstrap-server kafka-host:port --group test-group --reset-offsets --all-topics --to-current --execute

Specified-Offset 策略直接指定–to-offset

bin/kafka-consumer-groups.sh --bootstrap-server kafka-host:port --group test-group --reset-offsets --all-topics --to-offset --execute
 

Shift-By-N 策略直接指定–shift-by N。

bin/kafka-consumer-groups.sh --bootstrap-server kafka-host:port --group test-group --reset-offsets --shift-by --execute
 

DateTime 策略直接指定–to-datetime。

bin/kafka-consumer-groups.sh --bootstrap-server kafka-host:port --group test-group --reset-offsets --to-datetime 2019-06-20T20:00:00.000 --execute
 

Duration 策略,我们直接指定–by-duratio

bin/kafka-consumer-groups.sh --bootstrap-server kafka-host:port --group test-group --reset-offsets --by-duration PT0H30M0S --execute
 

 

Kafka系列(30)怎么重设消费组位移_第2张图片

 

你可能感兴趣的:(Kafka)