Kafka producer 端的工作逻辑及样例

基于Kafka2.1解读Producer原理 相信现在的javer对于Kafka应该都很熟悉了,不管是八股文还是工作中使用。虽然Kafka server是scala写的,但是client是java写的,所以咱们理解client的代码还是比较容易的,今天先来基于源码解读下Kafka Producer的主体流程Kafka的消息发送其实就是一个RPC的过程,有自己的网络协议、消息协议、消息序列化方式、数据批量发送(增加吞吐量)、超时处理、底层网络模型。不过Producer对于batch的复用,其实还是有一定的厉害之处的,等下次有空分析下~ 阅读详情

在这里插入图片描述

producer 的工作逻辑:

启动 producer 的线程将待发送消息封装成 ProducerRecord. 然后将其序列化发送给 partitioner, 再由后者确定了目标分区后一同发送给位于 producer 程序中的一块内存缓冲区. 而 producer 的另一个线程负责实时从缓冲区中提取出来准备就绪的消息封装成一个批次,发送给对应的 broker.

public class SimpleKafkaProducer {

public static void main(String[] args) {

    Properties props = new Properties();

    //broker地址
    props.put("bootstrap.servers", "localhost:9092");

    //请求时候需要验证
    props.put("acks", "all");

    //请求失败时候需要重试
    props.put("retries", 0);

    //内存缓存区大小
    props.put("buffer.memory", 33554432);

    //指定消息key序列化方式
    props.put("key.serializer",
            "org.apache.kafka.common.serialization.StringSerializer");

    //指定消息本身的序列化方式
    props.put("value.serializer",
            "org.apache.kafka.common.serialization.StringSerializer");

    Producer<String, String> producer = new KafkaProducer<>(props);

    for (int i = 0; i < 10; i++)
        producer.send(new ProducerRecord<>("test", Integer.toString(i), Integer.toString(i)));
    System.out.println("Message sent successfully");
    producer.close();
}

}

至少要指定 bootstrap.servers、key.serializer 及 value.serializer 这三个值.

bootstrap.servers
用于创建向 Kafka broker 服务器的链接,比如 k1:9092,k2:9092,k3:9092. 该参数指定多台机器只是为了故障转移使用. 这样即使某一台 broker 挂掉了,producer 重启后依然能通过该参数指定的其他 broker 连入 Kafka 集群(如果说我们这里只指定一台机器,那么如果这台 broker 挂了,你就算重启producer 也连不到kafka集群).

key.serializer
被发送到 broker 端的任何消息格式都必须是字节数组,因此消息的各个组件必须首先序列化.

value.serializer
对消息体进行序列化

2.构造 KafkaProducer 对象
Producer<String, String> producer = new KafkaProducer<>(props);

3.构造 ProducerRecord 对象.
new ProducerRecord<>(“my-topic”, Integer.valueOf(1));

发送消息

异步发送是通过 Callback(){} 回调来实现的.

同步发送是通过 Future.get() 一直等待结果来实现的.

异常分类

1.可重试异常:LeaderNotAvailableException、NotControllerException、NetworkException

2.不可重试异常:所有非继承 RetriableException 类的其他异常都属于不可重试异常.
RecordTooLargeException、SerializationException、KafkaException

关闭 producer

producer 程序结束时一定要关闭 producer!如果调用的是普通的无参 close 方法,producer 会被允许先处理完之前的发送请求后再关闭,即所谓的“优雅”退出。还有一种是待超时的关闭,时间一到,producer 会被强制结束,并立即丢弃所有未发送以及未应答的发送请求

producer 主要参数

acks 用于控制 producer 生产消息的持久性.
当 producer 发送一条消息给 Kafka 集群时,这条消息会被发送到指定 topic 分区 leader 所在的 broker 上,producer 等待从该 leader broker 返回写入的结果以确定消息是否被成功写入. 这一切完成后 producer 可以继续发送新的消息.
显然 leader 何时发送写入结果返给 producer 直接会影响消息的持久性甚至是 producer 端的吞吐量.acks 指定了再给 producer 发送响应前,leader broker 必须要确保已成功写入该消息的副本数. 当前 acks 有三个值:0、1、all.

acks=0——producer 不理睬 leader broker 端的处理结果,
acks=all或者-1,会等待 ISR 中所有副本都成功写入他们各自的本地日志后,才发送响应结果给 producer.

acks=1 leader broker 仅将该消写入本地日志后便发送响应结果 producer,而不需等待 ISR 中其他副本写入该消息.

buffer.memory 指定 producer 端用于缓存消息的缓冲区大小,单位是字节. 默认值是 32M.

compression.type 设置 producer 端是否压缩消息. 默认值是 none. 目前支持 GZIP、Snappy 和 LZ4.

retries 在发送失败时重试的次数,默认值是 0.

batch.size 默认值是 16KB 批次的大小.

linger.ms 控制消息发送时延行为的,默认值为 0. 表示该消息立即被发送,无须关心 batch 是否被填满.

max.request.size 用于控制 producer 发送请求的大小(控制 producer 端能发送的最大消息的大小).

request.timeout.ms 当 producer 发送请求给 broker 后,broker 需要在规定的时间范围内将处理结果返还给 producer.

消息分区机制

Java 版的 producer 会根据 murmur2 算法计算消息 key 的哈希值,然后对总分区数求模得到消息要发送到的目标分区号.
问题:Kafka 允许用户动态扩展分区不?
对于这个问题,首先需要明确一点的是 kafka 支持扩展分区,但是不支持减少分区. 新增分区后,各个分区上的消息不会重新分配. 比如说以前分区A上有30条消息,分区比上有30条消息,现在新增分区C,不会说消息均衡下,ABC三个分区各20条数据,而是说在后面的时候,消息通过模运算,可能落到A上,可能落到B上,也可能落到C上. 新增分区后,会多消息的顺序造成影响,也会影响消息落到那个分区. 现在说下为啥不能减少分区了,第一个问题是,减少分区上的消息怎么办了?如果保留的话直接插入到某个分区的尾部?还是说消息重平衡?这些都是需要考虑的问题.

参考:https://blog.youkuaiyun.com/u013256816/article/details/82804564

自定义分区:
1.创建一个类继承 Partitioner 接口,主要分区逻辑在 Partitioner.partition 中实现.
2.在用于构造 KafkaProducer 的 Properties 对象中设置 partitioner.class 参数.

消息序列化

目前内置的序列化类有:StringSerializer、DoubleSerializer 等

自定义序列化

1.定义数据对象格式
2.创建自定义序列化类,实现 Serializer 接口
3.在用于构造 KafkaProducer 的 Properties 对象中设置 key.serializer 或 value.serializer.

producer 拦截器

interceptor 使得用户在消息发送前以及 producer 回调逻辑前有机会对消息做一些定制化需求,比如修改消息等. producer 允许用户指定多个 producer 按序作用于同一条消息从而形成拦截链. interceptor 的实现接口:ProducerInterceptor.

onSend:该方法封装进 KafkaProducer.send 方法中,即它允许在用户主线程中. producer 确保消息被序列化以计算分区前调用该方法. 用户可以在该方法中对消息做任何操作,但最好不要修改消息所属的 topic 和分区,否则会影响目标分区的计算.

onAcknowledgement:该方法会在消息被应答之前或消息发送失败时调用,并且通常是在 producer 回调逻辑触发之前. onAcknowledgement 运行在 producer 的 I/O 线程中,因此不要在该方法中放入很“重”的逻辑,否则会拖慢 producer 的消息发送效率.

close:关闭 interceptor,主要用于执行一些资源清理工作.

无消息丢失配置

block.on.buffer.full=true
acks=all
retries=Integer.MAX_VALUE
max.in.flight.requests.per.connection=1
使用 KafkaProducer.send(record,callback)
unclean.leader.election.enable=false
replication.factory=3
min.insync.replicas=2
replication.factory>min.insync.replicas
enable.auto.commit=false

producer 端配置

block.on.buffer.full=true 内存缓冲区填满时 producer 处于阻塞状态并停止接收新的消息而不是抛出异常.
acks=all 必须等到所有 follower 都响应了发送消息才能认为提交成功.
retries=Integer.MAX_VALUE producer 不会重试那些肯定无法恢复的错误.
max.in.flight.requests.per.connection=1 防止 topic 同分区下的消息乱序问题.

broker 端配置

unclean.leader.election.enable=false 不允许非 ISR 中的副本被选举为 leader,从而避免 broker 端因为日志水位被截断导致消息丢失

replication.factory>=3 强调使用多分区保存消息.

min.insync.replicas > 1 用于控制某条消息被写入到 ISR 中的多少个副本才算成功,设置成大于 1 是为了提升 producer 端发送语义的持久性. 只有在 producer 端 acks 被设置成 all 时,这个参数才有意义.

确保 replication.factory>min.insync.replicas. 推荐配置成 replication.factory = min.insync.replicas + 1

消息压缩

producer 端压缩——broker 端保持——consumer 端解压缩.

压缩算法

GZIP LZ4 SNAPPY

对于 Kafka 而言 LZ4 > Snappy > GZip

多线程处理

多线程单 KafkaProducer 实例
多线程多 KafkaProducer 实例

如果是分区数不是很多的 Kafka 集群而言,第一种比较合适,若是有超多分区的集群,第二种方式更合适.

聊聊 Kafka:Producer 源码解析 一、前言 前面几篇我们讲了关于 Kafka 的基础架构以及搭建,从这篇开始我们就来源码分析一波。我们这用的 Kafka 版本是 2.7.0,其 Client 端是由 Java 实现,Server 端是由 Scala 来实现的,在使用 Kafka 时,Client 是用户最先接触到的部分,因此,我们从 Client 端开始,会先从 Producer 端开始,今天我们就来对 Producer 源码解析一番。 二、Producer 使用 首先我们先通过一段代码来展示 KafkaProducer 的使用方法。 阅读详情

相关推荐

Kafka Producer模块分析

1. 概述 一、Kafka Producer包含哪些部分 其实我们讨论producer时,指的是用户接触的clients.producer这个util包,其中包含了发送数据到哪台机器、怎样序列化、分批发送与拒绝消息等等的发送策略。 但这些讨论不包括Kafka接到这些消息后怎样处理的问题,这些是broker(即kafka server端)需要去处理的部分。 二、Producer与Broker的关系 producer会维护将要发送的topic表,在必要时向broker要这些topic的元信息,并在client端

陀氏 821

kafka实现异步发送_Kafka producer端开发代码实例

一、producer工作流程producer使用用户启动producer的线程,将待发送的消息封装到一个ProducerRecord类实例,然后将其序列化之后发送给partitioner,再由后者确定目标分区后一同发送到位于producer程序中的一块内存缓冲区中。而producer的另外一个线程(Sender线程)则负责实时从该缓冲区中提取出准备就绪的消息封装进一个批次(batch),统一发送给...

weixin_34304538的博客 824

告别手动画图!用Cadence SKILL写一个参数化电感PCell(附完整代码)

本文详细介绍了如何使用Cadence SKILL语言开发参数化电感PCell,实现电感版图的自动化生成。通过动态调整线宽、圈数等几何参数,自动创建端口并进行工艺规则校验,大幅提升高频电路设计效率。附完整代码示例,帮助工程师快速掌握PCell开发技巧。

weixin_30684743的博客 367

kafka生产者实例-精简可用

不啰嗦,直接上代码(下面是个完整的生产者实例): package com.z.kafka; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; import org.apache.kafka.clients.producer.KafkaProducer; import org..

Z的博客 1188

墨刀原型设计工具操作使用指南及实践操作

该指南通过异常场景处理、像素级参数说明、复杂交互示例,覆盖了墨刀操作的全细节,适合从新手到资深用户的进阶学习。结合 PlantUML 思维导图的层级化展示,可快速定位具体功能的操作要点与问题解决方法,真正实现 “照指南即可操作” 的实用价值。

hy行者勇哥的博客 4948

点云中概念:匹配、配准、融合

匹配,是寻找与一幅图相似的图像(不对寻找到的图像做矫正)。 配准,是寻找相似图像但是变形后的图像(需要做一些旋转之类的校正变换)。 融合,是多幅图像连接成一幅大图,视频集成中用的比较多。 1)匹配: 2)配准: 比如由于固定式激光雷达受测量方式的限制和被测物体集合形状的限制,固定的话一次只能扫描被测物体有限范围的点云数据(比如一个面??),这需要在多个视角下进行多次扫描(就是将激光雷达前后左右四个面都扫一下??对的),然而每个视角下得到点云数据都具有独立的坐标系,无法直接进行拼接(拼接就是将四个面

m0_37957160的博客 1万+

如何在JMeter中玩懂KAFKA

通过JMeter来理解KAFKA的基本原理,能帮助我们如何来压测KAFKA。内容详细。值得细细品尝。

qq_38209830的博客 4305

【RT-DETR涨点改进】全网独家首发Conv改进篇 | SCI一区 2025 | RT-DETR引入轻量级CGHalfConv通道分组半卷积模块,含多种创新改进、有效提升检测精度

本文介绍引入 GC Half-convolution 模块可以显著提升 RT-DETR 在资源受限环境下的性能。该模块通过通道分组与半卷积结合,有效减少了参数量与计算量,增强了模型对不同尺度和复杂背景下目标的特征提取能力。在保持模型轻量化的同时,GC Half-convolution 能够更细致地区分目标的边缘纹理、颜色、结构等关键信息,从而提升检测精度。特别是在面对小目标、多类别、形态相近的目标时,该模块能提取更具判别性的局部与全局特征,优化 RT-DETR 的检测效果,并加快推理速度。

Ai缝合怪、助力小伙伴高效发论文 745

jmeter向kafka中写入数据

1.在jmeter中下载kafka插件:在jmeter"选项"菜单中选择"plugins Manager"安装ID KafKaMeter和kafka Support两个插件2.在配置元件中添加KafkaProducerConfig下图中只需要配置kafka Brokers,其他的无需填写3.添加KafkaProducerSampler 配置KafkaProducerSampler4.执行脚本5.服务器中消费数据...

liyanbin1214的博客 1759

排队论 | 排队论建模方法

排队论 | 排队论建模方法

算法如诗的博客 352

Cadence PCB仿真 使用Allegro PCB SI为BRD文件创建通用型IBIS模型的方法图文教程

本文简单介绍使用Allegro PCB SI软件为BRD PCB设计文件中的元器件创建IBIS模型的方法。

fydar的博客 2169

Jmeter Kafka Sampler(Producer)

之前写了一个Jmeter kafka 插件是基于公司对kafka二次封装写的,这次基于原生kafka写一个插件,如下,废话不多说,中心思想是一样的,可以参考我上篇文章。Jmeter Kafka插件开发之Sampler篇。

C'mon的博客 1464

Q3D提取PCB走线RLCG参数

介绍一种提取PCB走线寄生电容和寄生电感的方法

sinat_15150363的博客 2917

Kafka:Producer生产者发送逻辑 - 源码

1. 简述注:kafka版本为0.10.1.0 本文大致梳理Producer的发送过程,若有不对请指出。 我们在使用producer客户端,基本使用方法如下:KafkaProducer<byte[], byte[]> producer = new KafkaProducer<byte[], byte[]>(props); producer.send(record, cb);2. 源码 - Kaf

Nothing is impossible 5255

小白也能懂!一步步教你用FPGA加速YOLO目标检测(入门篇)

安装到 PYNQ 开发板中。该库为 PYNQ 平台提供了对量化神经网络(如 YOLO)的硬件加速支持。确保你的电脑已连接到外网,如 WiFi 或热点(手机热点理论上也可用,未实测)。当你看到安装成功的提示后,打开 Jupyter Notebook,你会发现在。趁这个机会,泡了杯茶,刷了会儿手机,顺便感慨了一下开源社区的强大……页面中多出了一些新的项目文件夹 —— 这就是我们刚才安装的。参数,浅拷贝只克隆最近一次提交,减少数据量,避免超时问题。初始化,打开该文件,即可运行我们的Tiny YOLO。

FJN110的博客 1597

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

kafka实战篇(一):Producer消息发送实战

本文对kafka生产者发送消息的流程进行了详细的解释和实战,其中包含了新版本的kafka对于同步发送消息和异步发送消息的api实现,以及kafka源码里的回调函数和架构内部的失败重试机制等都给出了底层的详细解释及实战demo。

静待花开 1万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Kafka 之 - Producer

why Kafka 支持多个生产者,分布式系统中往往有多个微服务向一个kafka集群发送消息; 支持多个消费者从一个Kafka集群中消费消息,可以通过消费者组实现多个消费者同时协作消费消息。 允许消费者非实时读取消息 partition 同一个partition中的消息顺序消费 不同partition中的消息消费顺序不保证 ISR controller Kafka集群中第一个启动的broker会通过在zookeeper中创建临时节点/controller 来试图让自己成为controller,其他节点会在该

Ellen的博客 1502

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Kafka Producer

本文采用Kafka 0.8.2版本 OverviewProducer的作用生成数据(消息),并将其发送到Kafka集群(brokers)中。将消息发送给谁Producer在向Kafka集群发送消息时,需要指定发送到哪一个topic中。除此之外,还可以指定发送到该topic的哪一个partition中。消息的构成一条消息的成分,从逻辑上来说,由真正的消息数据(message)和元数据(metadat

肖韬的BLOG 5303

【Kafka】深入图解Kafka producer 发送过程

文章目录producer 发送过程参考 producer 发送过程 在新版本的kafka中(从0.9开始),其实只有异步方式一种,是批量发送的方式 在producer端,存在2个线程: 一个是producer主线程,用户端调用send消息时,是在主线程执行的,数据被缓存到RecordAccumulator中,send方法即刻返回,也就是说此时并不能确定消息是否真正的发送到broker。 另外一个是sender IO线程,其不断轮询RecordAccumulator,满足一定条件后,就进行真正的网络IO发送

m0_45406092的博客 5321

Apache Kafka笔记(三):Producer的工作原理

Producer工作原理

杂草一亩 5153

Kafka之Producer网络传输

我们首先回想一下Producer消息发送的整体流程客户端线程会不断地写入数据,当前线程并不会阻塞,而是马上返回。这个时候消息被Producer放在了缓存内,消息并没有真正发送出去Producer内部为每个Partition维护了一个RecordBatch的队列,先进先出的模式,统称为RecordAccumulator,数据第一步会先放在这个组件中。放在这个组件中的数据什么时候会真正发送出去呢?这里其实是“大巴车”逻辑(大巴车逻辑是指:1、如果某辆大巴车已经坐满人了,这个时候无条件立即发车。

sjzsylkn的专栏 1259

Kafka - Producer发送原理:异步发送、批量缓存、分区器逻辑

4. 分区器(Partitioner):消息如何路由? 🧭 Kafka Producer 的分区策略直接影响数据分布的均匀性和顺序性。核心逻辑由 Partitioner 接口 控制: public interface Partitioner extends Configurable, Closeable { int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cl

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

Kafka服务端处理producer请求原理解析

本文深入解析了Kafka服务端处理Producer请求的核心流程。首先通过RequestHandlerPool接收请求,经KafkaApis路由到ProduceRequest处理逻辑。随后ReplicaManager将数据写入本地日志,经过Partition校验后调用LogSegment执行文件写入操作。关键点包括:数据分片处理、日志分段策略(基于大小/时间)、索引文件维护等。整个流程展现了Kafka高效处理写入请求的分层设计,从请求接收、权限校验到最终数据持久化,各组件职责明确,共同保障了高吞吐的消息写入

liangsheng_g的专栏 962

Kafka 新版Producer Java版代码阅读

Kafka Producer 代码阅读Kafka在0.8.2.1出了新版Producer,支持ack(仅Java版,因为通过JavaClient实现的)。因此对代码进行了简单阅读,并记录如下:接口如下:public Future<RecordMetadata> send(ProducerRecord<K,V> record, Callback callback) 封装一个Record之后,每次调用

mengyou0304的专栏 3698

Kafka 基础教程 — producer端设计

作者简介:大家好,我是码炫码哥,前中兴通讯、美团架构师,现任某互联网公司CTO,兼职码炫课堂主讲源码系列专题代表作:《jdk源码&多线程&高并发》,《深入tomcat源码解析》,《深入netty源码解析》,《深入dubbo源码解析》,《深入springboot源码解析》,《深入spring源码解析》,《深入redis源码解析》等联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬。

smart_an的专栏 920
上一篇: 虚拟机运行时栈帧的结构
下一篇: tomcat类加载机制
^一剪梅^
博客等级 码龄12年 4粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值