kafka 拉取的数据排序_Kafka 源码解析之 Consumer Poll 模型(七)

在上一篇问文章中已经介绍一个 Consumer 实例如何加入到一个 group 中,它是 Consumer Poll 模型第一步要做的事件,本文会完整讲述一个 Consumer 实例在 poll 模型过程中会做哪些事情,只有理解了 poll 模型才能更好地理解 Consumer 端的处理逻辑。

Consumer 示例

这里以一个 Consumer 的实例代码作为开始,一个比较常见的 Consumer 示例代码如下所示,其主要包含一下几个步骤:

  1. 构造 Propertity,进行 consumer 相关的配置;
  2. 创建 KafkaConsumer 的对象 consumer;
  3. 订阅相应的 topic 列表;
  4. 调用 consumer 的 poll 方法拉取订阅的消息。

前面两步在 Consumer 底层上只是创建了一个 consumer 对象,第三步只有记录一下订阅的 topic 信息,consumer 实际的操作都是第四步,也就是在 poll 方法中实现的,这也是 poll 模型对于理解 consumer 设计非常重要的原因。

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;

import java.util.Arrays;
import java.util.Properties;

/**
 * 自动 commit 的情况
 * Created by matt on 16/7/14.
 */
public class ConsumerAutoOffsetCommit {
    private static String topic;
    private static String group;
    public static void main(String[] args) {
        Properties props = new Properties();
        topic=args[0];
        group=args[1]; // auto-offset-commit
        props.put("bootstrap.servers", "XXX:9092,XXX:9092");
        props.put("group.id", group);
        props.put("auto.offset.reset", "earliest");
        props.put("enable.auto.commit", "true"); // 自动commit
        props.put("auto.commit.interval.ms", "1000"); // 自动commit的间隔
        props.put("session.timeout.ms", "30000");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList(topic)); // 可消费多个topic,组成一个list
        while (true) {
            ConsumerRecords<String, String> records = consumer.poll(100);
            for (ConsumerRecord<String, String> record : records) {
                System.out.printf("offset = %d, key = %s, value = %s n", record.offset(), record.key(), record.value());
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Poll 模型综述

当一个 consumer 对象创建之后,只有 poll 方法调用时,consumer 才会真正去连接 kafka 集群,进行相关的操作,其 poll 方法具体实现如下:

//timeout(ms): buffer 中的数据未就绪情况下,等待的最长时间,如果设置为0,立即返回 buffer 中已经就绪的数据
public ConsumerRecords<K, V> poll(long timeout) {
    acquire();
    try {
        if (timeout < 0)
            throw new IllegalArgumentException("Timeout must not be negative");

        if (this.subscriptions.hasNoSubscriptionOrUserAssignment())
            throw new IllegalStateException("Consumer is not subscribed to any topics or assigned any partitions");

        // poll for new data until the timeout expires
        long start = time.milliseconds();
        long remaining = timeout;
        do {
            Map<TopicPartition, List<ConsumerRecord<K, V>>> records = pollOnce(remaining);
            //note: 从订阅的 partition 中拉取数据,pollOnce() 才是对 Consumer 客户端拉取数据的核心实现
            if (!records.isEmpty()) {
                // 在返回数据之前,发送下次的 fetch 请求,避免用户在下次获取数据时线程 block
                if (fetcher.sendFetches() > 0 || client.pendingRequestCount() > 0)
                    client.pollNoWakeup();

                if (this.interceptors == null)
                    return new ConsumerRecords<>(records);
                else
                    return this.interceptors.onConsume(new ConsumerRecords<>(records));
            }

            long elapsed = time.milliseconds() - start;
            remaining = timeout - elapsed;
        } while (remaining > 0);

        return ConsumerRecords.empty();
    } finally {
        release();
    }
}

consumer poll 方法主要做了以下几件事情:

  1. 检查这个 consu
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kafka拉取数据的配置设置主要包括以下几个方面: 1. 消费者组的配置:消费者组是Kafka中用于分组管理消费者的概念,可以通过设置消费者组来实现负载均衡和故障转移。在消费者代码中,需要设置消费者组的ID,以便Kafka可以将多个消费者组织成一个消费者组。 2. 消费者配置:消费者配置包括消费者ID、自动提交偏移量、读取超时时间等参数。消费者ID是用于唯一标识消费者的字符串,自动提交偏移量可以设置消费者是否自动提交读取位置,读取超时时间可以设置消费者等待数据的超时时间。 3. 消费者订阅的主题和分区:在消费者代码中,需要指定消费者订阅的主题和分区,以便Kafka可以将消息发送到正确的消费者。 4. 消费者的消费逻辑:在消费者代码中,需要编写消费逻辑,以处理从Kafka中读取的消息。消费逻辑可以根据业务需求进行自定义,例如将消息写入数据库、发送到其他系统等。 下面是一个使用Java语言编写的Kafka消费者的配置示例: ```java Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("group.id", "test-group"); props.put("enable.auto.commit", "true"); props.put("auto.commit.interval.ms", "1000"); props.put("session.timeout.ms", "30000"); props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); consumer.subscribe(Arrays.asList("test-topic")); while (true) { ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100)); for (ConsumerRecord<String, String> record : records) { System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value()); // TODO: 消费逻辑 } } ``` 在这个示例中,我们通过设置Properties对象来配置消费者的参数,包括Kafka集群的地址、消费者组ID、自动提交偏移量、反序列化器等。然后创建一个KafkaConsumer对象,并通过subscribe()方法订阅一个主题。在while循环中,我们通过poll()方法从Kafka中读取消息,然后通过for循环遍历消息,并对消息进行处理(这里只是简单地打印消息的内容)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值