从kafka的acks参数来理解:回调函数

一般情况下,producer在发送一条数据时就会登记回调函数(回调函数暂时不运行,由于是异步,主程序会继续发送其他数据),数据到达服务器broker上指定分区时,服务器会通知producer已经发送成功。producer收到消息后就会触发回调函数,可以显示这条数据在服务器端的一些信息(偏移量,分区等)。

Kafka的producer:

public static void producerSendWithCallback(){
        Properties properties = new Properties();
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,kafka_servers);
        properties.put(ProducerConfig.ACKS_CONFIG,"all");           //ack参数
        properties.put(ProducerConfig.RETRIES_CONFIG,"0");
        properties.put(ProducerConfig.BATCH_SIZE_CONFIG,"16384");
        properties.put(ProducerConfig.LINGER_MS_CONFIG,"1");
        properties.put(ProducerConfig.BUFFER_MEMORY_CONFIG,"33554432");
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");

        // Producer的主对象
        Producer<String,String> producer = new KafkaProducer<>(properties);

        // 消息对象 - ProducerRecoder
        for(int i=0;i<5;i++){
            ProducerRecord<String,String> record =
                    new ProducerRecord<>(TOPIC_NAME,"key-"+i,"value-"+i);

            producer.send(record, new Callback() {
                @Override
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    System.out.println(
                            "time : "+recordMetadata.timestamp()  +",partition : "+recordMetadata.partition()+" , offset : "+recordMetadata.offset());
                }
            });
        }
        // 所有的通道打开都需要关闭
        producer.close();
    }

设置acks=all
Leader接收到消息并写入磁盘分区之后(写入磁盘当然才能知道数据的offset信息),还必须要求ISR列表里跟Leader保持同步的那些Follower都要把消息同步写入磁盘分区,才能认为这条消息是写入成功了。

properties.put(ProducerConfig.ACKS_CONFIG,"all");

回调函数返回结果:

time : 1611678310197,partition : 1 , offset : 275
time : 1611678310207,partition : 1 , offset : 276
time : 1611678310207,partition : 1 , offset : 277
time : 1611678310207,partition : 0 , offset : 200
time : 1611678310207,partition : 0 , offset : 201

消费者信息(注意:回调函数的结果和消费者打印的结果不是一一对应的):

[hadoop@hadoop000 kafka_2.11-2.2.1]$ kafka-console-consumer.sh --bootstrap-server hadoop000:9092 --topic topic_test
value-1
value-2
value-0
value-3
value-4

设置acks=0
把消息发送出去,不管那条数据有没有在哪怕Partition Leader上落到磁盘,我就不管他了,直接就认为这个消息发送成功了。

properties.put(ProducerConfig.ACKS_CONFIG,"0");

回调函数返回结果:

time : 1611678235720,partition : 1 , offset : -1
time : 1611678235729,partition : 1 , offset : -1
time : 1611678235729,partition : 1 , offset : -1
time : 1611678235729,partition : 0 , offset : -1
time : 1611678235729,partition : 0 , offset : -1

所以获取不到offset的值。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值