Kafka学习---2、kafka生产者、异步和同步发送API、分区、生产经验(一)

简介: Kafka学习---2、kafka生产者、异步和同步发送API、分区、生产经验(一)

1、kafka生产者

1.1 生产者消息发送流程

1.1.1 发送原理

在消息发生的过程中,设计到了两个线程——main线程和Sender线程。在main线程中创建了一个双端队列RecordAccumulator。main线程将消息发给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到Kafka Broker。

6b57d2400a1f40a5aba07938577a1588.pngbatch.size:只有数据积累到batch.size之后,sender才会发送数据。默认16k

linger.ms:如果数据迟迟未达到batch.size,sender等待linger.ms设置的时间到了之后就会发送数据。单位ms,默认值数0ms,表示没有延迟。

应答acks:

0:生产者发生过来的数据,不需要等数据落盘应答。

1:生产者发生过来的数据,Leader收到数据后应答

-1(all):生产者发送过来的数据,Leader和ISR队列里面的所有节点收齐数据后应答。-1和all等价。

1.1.2 生产者重要参数列表


微信图片_20230804133249.jpg

1.2 异步发送API

1.2.1 普通异步发送

1、需求:创建 Kafka 生产者,采用异步的方式发送到 Kafka Broker

2、代码编写

(1)创建工程(KafkaDemo)

(2)导入依赖

<dependencies>
 <dependency>
 <groupId>org.apache.kafka</groupId>
 <artifactId>kafka-clients</artifactId>
 <version>3.0.0</version>
 </dependency>
</dependencies>

(3)创建包名org.zhm.producer

(4)编写不带回调函数的API代码

package org.zhm.producer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;
/**
 * @ClassName CustomProducer
 * @Description TODO
 * @Author Zouhuiming
 * @Date 2023/6/12 18:35
 * @Version 1.0
 */
public class CustomProducer {
    public static void main(String[] args) {
        //1、创建kafka生产者的配置对象
        Properties properties=new Properties();
        //2、给kafka配置对象添加配置信息:bootstrap.servers
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");
        //key,value序列化(必须):key.serializer,value.serializer
        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");
        //3、创建kafka生产者对象
        KafkaProducer<String,String> kafkaProducer=new KafkaProducer<String, String>(properties);
        //4、调用send()方法,发生消息
        for (int i = 0; i < 5; i++) {
            kafkaProducer.send(new ProducerRecord<>("first","zhm"+i));
        }
        //5、关闭资源
        kafkaProducer.close();
    }
}

(5)测试

①在 hadoop102 上开启 Kafka 消费者。

bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first

8c1f7e1e98d44b549fe4ad81362d4483.png

②在 IDEA 中执行代码,观察 hadoop102 控制台中是否接收到消息。

06f92e2fc23a4b729bd6288cfcda233f.png

1.2.2 带回调函数的异步发送

回调函数会在Producer收到ack时调用,为异步调用,该方法有两个参数,分别是元数据信息(RecordMetadata)和异常信息·(Exception),如果Exception为null,说明消息发生成功,如果Exception不为null,说明消息发送失败。

注意:消息发送失败会自动重试,不需要我们在回调函数中手动重试。

package org.zhm.producer;
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.Properties;
/**
 * @ClassName CustoProducerCallback
 * @Description TODO
 * @Author Zouhuiming
 * @Date 2023/6/12 18:44
 * @Version 1.0
 */
public class CustoProducerCallback {
    public static void main(String[] args) throws InterruptedException {
        //1、创建kafka生产者的配置对象
        Properties properties=new Properties();
        //2、给kafka配置对象添加配置信息
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");
        //key、value序列化(必须)
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());
        //3、创建kafka生产者对象
        KafkaProducer<String,String> producer=new KafkaProducer<>(properties);
        //4、调用send()方法 发送信息
        for (int i = 0; i < 6; i++) {
            //添加回调
            producer.send(new ProducerRecord<>("first", "zhm" + i), new Callback() {
                //该方法在Producer收到ack时调用,为异步调用
                @Override
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    if (e==null){
                        //没有异常,输出信息到控制台
                        System.out.println("主题:"+recordMetadata.topic()+"->"+"分区:"
                                +recordMetadata.partition());
                    }
                    else {
                        //出现异常打印
                        e.printStackTrace();
                    }
                }
            });
            //延迟一会会看到数据发往不同分区
            Thread.sleep(20);
        }
        //5、关闭资源
        producer.close();
    }
}

1、测试

①在 hadoop102 上开启 Kafka 消费者。

bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first

②在 IDEA 中执行代码,观察 hadoop102 控制台中是否接收到消息。


c0ac0c73271945f9b8f1ba2747f9e82a.png

1.3 同步发送API

只需在异步发送的基础上,再调用一下 get()方法即可。

package org.zhm.producer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
/**
 * @ClassName CustomProducerSync
 * @Description TODO
 * @Author Zouhuiming
 * @Date 2023/6/12 18:58
 * @Version 1.0
 */
public class CustomProducerSync {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //1、创建kafka生产者的配置对象
        Properties properties=new Properties();
        //2、给kafka配置对象添加配置信息
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");
        //key、value序列化
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());
        //3、创建kafka生产者对象
        KafkaProducer<String,String> producer=new KafkaProducer<>(properties);
        //4、调用send方法,发送信息
        for (int i = 0; i < 10; i++) {
            //异步发送 默认
//            producer.send(new ProducerRecord<>("first","zhm"+i));
            //同步发送
            producer.send(new ProducerRecord<>("first","zhmzhm"+i)).get();
        }
        //5、关闭资源
        producer.close();
    }
}

1、测试

①在 hadoop102 上开启 Kafka 消费者。

bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first

②在 IDEA 中执行代码,观察 hadoop102 控制台中是否接收到消息。


3e10bb50bc4b4f8191d52875c7e83f2f.png

1.4 生产者分区

1.4.1 分区好处

1、便于合理使用储存资源,每个Partition在一个Broker上储存,可以把海量的数据按照分区切割成一块一块数据储存在多台Broker上。合理控制分区的任务,可以实现负载均衡的效果。

2、提高并行度,生产者可以以分区为单位发送数据;消费者可以以分区为单位进行消费数据。

711fce8d637b4d66b5e1dba629880b4f.png

1.4.2 生产者发生消息的分区

1、默认分区器DefaultPartitioner

(1)指明partition的情况下,直接将指明的值作为partition值;例如partition=0,所有数据写入分区0。

(2)没有指明partition值但有key的情况下,将key的hash值与topic的partition数进行取余得到partition值;例如:key1的hash值=5, key2的hash值=6 ,topic的partition数=2,那么key1 对应的value1写入1号分区,key2对应的value2写入0号分区。

(3)既没有partition值又没有key值的情况下,Kafka采用Sticky Partition(黏性分区器),会随机选择一个分区,并尽可能一直

使用该分区,待该分区的batch已满或者已完成,Kafka再随机一个分区进行使用(和上一次的分区不同)。

例如:第一次随机选择0号分区,等0号分区当前批次满了(默认16k)或者linger.ms设置的时间到, Kafka再随机一个分区进

行使用(如果还是0会继续随机)。

2、案例一

将数据发往指定 partition 的情况

package org.zhm.producer;
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.Properties;
/**
 * @ClassName CustomProducerCallbackPartitions
 * @Description TODO
 * @Author Zouhuiming
 * @Date 2023/6/12 19:10
 * @Version 1.0
 */
public class CustomProducerCallbackPartitions {
    public static void main(String[] args) {
        //1、创建kafka生产者的配置对象
        Properties properties=new Properties();
        //2、给kafka配置对象添加配置信息
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");
        //键值序列化
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());
        //3、创建生产者对象
        KafkaProducer<String ,String> producer=new KafkaProducer<String, String>(properties);
        //4、调用send方法,发送信息
        for (int i = 0; i < 5; i++) {
            //指定数据发送到1号分区,key1为空
            producer.send(new ProducerRecord<>("first", 1, "", "zhm" + i), new Callback() {
                @Override
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    if (e==null){
                        System.out.println("主题:"+recordMetadata.topic()+"->"+"分区:"+recordMetadata.partition());
                    }else {
                        e.printStackTrace();
                    }
                }
            });
        }
        //5、关闭资源
        producer.close();
    }
}

(1)测试

①在 hadoop102 上开启 Kafka 消费者。

bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first

②在 IDEA 中执行代码,观察 hadoop102 控制台中是否接收到消息。


5e6039e2b8944336a7ad4e5add511dd4.png


相关文章
|
8月前
|
机器学习/深度学习 人工智能 缓存
电商 API 接口:开启全平台商品信息同步新时代
在数字化浪潮下,电商平台激增,消费者跨平台购物成为常态。然而,商品信息分散导致数据不一致、库存混乱等问题。电商 API 接口应运而生,通过标准化数据交换,实现多平台商品信息实时同步,提升运营效率、降低成本、增强用户体验,成为企业数字化转型的关键引擎。
432 0
|
7月前
|
存储 JSON 监控
淘宝/天猫:通过商品详情API实现多店铺商品信息批量同步,确保价格、库存实时更新
在电商运营中,管理多个淘宝或天猫店铺的商品信息(如价格、库存)耗时易错。本文介绍如何通过淘宝/天猫开放平台的商品详情API,实现自动化批量同步,确保信息实时更新。内容涵盖API调用、多店铺数据处理、实时更新策略及注意事项,助您高效管理多店铺商品信息。
468 0
|
8月前
|
人工智能 JSON 监控
电商 API 赋能,多平台促销活动精准同步
在电商多平台促销中,手动管理易导致价格混乱、库存超卖等问题。电商 API 通过自动化实现促销活动的精准同步,提升效率、减少错误,助力企业高效运营,实现销售增长与成本节约,是电商数字化转型的关键工具。
200 0
|
9月前
|
供应链 安全 API
淘宝API一键同步库存,销量翻倍轻松实现!
在电商竞争激烈的当下,库存管理是提升销量的关键。淘宝开放平台提供API接口,支持一键同步库存,实现线上线下数据实时更新,避免缺货或超卖。本文详解操作步骤,并附Python示例代码,助你轻松掌握自动化库存管理,提升转化率,实现销量翻倍。
532 0
|
9月前
|
JSON 人工智能 自然语言处理
根据标题利用API实现电商多平台同步:省时省力生成文章
在电商运营中,多平台同步产品信息、库存和订单数据至关重要。手动操作耗时易错,而通过API实现自动化同步,不仅能提升效率,还可结合内容生成工具自动创建产品文章。本文详解如何利用API完成数据同步与内容生成,帮助商家节省时间、减少错误、优化成本,提升运营效率。
172 0
|
消息中间件 存储 缓存
kafka 的数据是放在磁盘上还是内存上,为什么速度会快?
Kafka的数据存储机制通过将数据同时写入磁盘和内存,确保高吞吐量与持久性。其日志文件按主题和分区组织,使用预写日志(WAL)保证数据持久性,并借助操作系统的页缓存加速读取。Kafka采用顺序I/O、零拷贝技术和批量处理优化性能,支持分区分段以实现并行处理。示例代码展示了如何使用KafkaProducer发送消息。
|
消息中间件 存储 运维
为什么说Kafka还不是完美的实时数据通道
【10月更文挑战第19天】Kafka 虽然作为数据通道被广泛应用,但在实时性、数据一致性、性能及管理方面存在局限。数据延迟受消息堆积和分区再平衡影响;数据一致性难以达到恰好一次;性能瓶颈在于网络和磁盘I/O;管理复杂性涉及集群配置与版本升级。
585 1
|
消息中间件 Java Kafka
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
466 1
|
消息中间件 Java Kafka
Kafka不重复消费的终极秘籍!解锁幂等性、偏移量、去重神器,让你的数据流稳如老狗,告别数据混乱时代!
【8月更文挑战第24天】Apache Kafka作为一款领先的分布式流处理平台,凭借其卓越的高吞吐量与低延迟特性,在大数据处理领域中占据重要地位。然而,在利用Kafka进行数据处理时,如何有效避免重复消费成为众多开发者关注的焦点。本文深入探讨了Kafka中可能出现重复消费的原因,并提出了四种实用的解决方案:利用消息偏移量手动控制消费进度;启用幂等性生产者确保消息不被重复发送;在消费者端实施去重机制;以及借助Kafka的事务支持实现精确的一次性处理。通过这些方法,开发者可根据不同的应用场景灵活选择最适合的策略,从而保障数据处理的准确性和一致性。
1528 9
|
消息中间件 监控 Kafka
实时计算 Flink版产品使用问题之处理Kafka数据顺序时,怎么确保事件的顺序性
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。