对外开放的英文放翻译放英语怎么说-grown up


2023年3月31日发(作者:12月)

Kafkaproducer介绍

Kafka0.9版本正式使⽤Java版本的producer替换了原Scala版本的producer。本⽂着重讨论新版本producer的设计原理以及基本的使⽤⽅法。

新版本Producer

⾸先明确⼀下,新版本producer指的是roducer,⽽不是er。如果你依然在使⽤后者,我们强烈建

议你赶快升级到Kafka0.9以后的版本。

基本数据结构

新版本客户端(包含新版本producer和新版本consumer)重写了之前服务器端代码提供的很多数据结构以摆脱对服务器端代码的依赖。其中有⼀些是你

理解新版本producer所必需的,它们包括(但不限于):

ProducerRecord

⼀个ProducerRecord表⽰⼀条待发送的消息记录,主要由5个字段构成:

topic 所属topic

p适合发朋友圈正能量短句 artition所属分区

key键值

value消息体

timestamp时间戳

ProducerRecord允许⽤户在创建消息对象的时候就直接指定要发送的分区,这样producer后续发送该消息时可以直接发送到指定分区,⽽不⽤先通过

Partitioner计算⽬标分区了。另外,我们还可以直接指定消息的时间戳——但⼀定要慎重使⽤这个功能,因为它有可能会令时间戳索引机制失效(笔者

曾经直接指定时间戳故意打乱发送顺序进⾏测试,⽐如先发送消息的时间戳⼤于后发送消息的时间戳,最后发现通过时间戳定位消息时会发⽣混乱。

为此我还特意开了⼀个jiraissue,不过被认为是\"当前不被⽀持的⽤法\")

RecordMetadata

该类表⽰Kafka服务器端返回给客户端的消息的元数据信息,包含以下内容:亡羊补牢

offset该条消息的位移

timestamp消息时间戳

topic+partition所属topic的分区

checksum消息CRC32码

serializedKeySize序列化后的消息键字节数

serializedValueSize序列化后的消息体字节数

上⾯的元数据信息前3项信息是⽐较重要的,producer端可以使⽤这些信息做⼀些消息发送成功之后的处理,⽐如写⼊⽇志等。

⼯作流程

如果把Producer统⼀看成⼀个盒⼦,那么整个producer端的⼯作原理便如下图所⽰:

⼤体上来说,⽤户⾸先构建待发送的消息对象ProducerRecord,然后调⽤KafkaProducer#send⽅法进⾏发送。KafkaProducer接收到消息后⾸先对其

进⾏序列化,然后结合本地缓存的元数据信息⼀起发送给partitioner去确定⽬标分区,最后追加写⼊到内存中的消息缓冲池(accumulator)。此时

KafkaProducer#send⽅法成功返回。

KafkaProducer中还有⼀个专门的SenderIO线程负责将缓冲池中的消息分批次发送给对应的broker,完成真正的消息发送逻辑。

基本设计特点

结合源代码,笔者认为新版本的producer从设计上来说具有以下⼏个特点(或者说是优势):

1.总共创建两个线程:执⾏KafkaPrducer#send逻辑的线程——我们称之为“⽤户主线程”;执⾏发送逻辑的IO线程——我们称之为“Sender线程”

2.不同于Scala⽼版本的producer,新版本producer完全异步发送消息,并提供了回调机制(callback)供⽤户判断消息是否成功发送

ng机制——“分批发送“机制。每个批次(batch)中包含了若⼲个PRODUCE请求,因此具有更⾼的吞吐量

4.更加合理的默认分区策略:对于⽆key消息⽽⾔,S古诗一千首 cala版本分区策略是⼀段时间内(默认是10分钟)将消息发往固定的⽬标分区,这容易造成消

息分布的不均匀,⽽新版本的producer采⽤轮询的⽅式均匀地将消息分发到不同的分区

5.底层统⼀使⽤基于Selector的⽹络客户端实现,结合Java提供的Future实现完整地提供了更加健壮和优雅的⽣命周期管理。

其实,新版本producer的设计优势还有很多,诸如监控指标更加完善等这样的就不⼀⼀细说了。总之,新版本producer更加地健壮描写秋天的古诗词 ,性能更好~

关键参数

新版本producer的参数有⼏⼗个之多,我们重点了解其中的6个就够了,它们是:

我把它列在了⾸位,因为该参数对于调优producer⾄关重要。之前提到过新版producer采⽤分批发送机制,该参数即控制⼀个

batch的⼤⼩。默认是16KB

acks关乎到消息持久性(durability)的⼀个参数。⾼吞吐量和⾼持久性很多时候是相⽭盾的,需要先明确我们的⽬标是什么?⾼吞吐

量?⾼持久性?亦或是中等?因此该参数也有对应的三个取值:0,-1和1

减少⽹络IO,节省带宽之⽤。原理就是把原本需要多次发送的⼩batch,通过引⼊延时的⽅式合并成⼤batch发送,减少了⽹络

传输的压⼒,从⽽提升吞吐量。当然,也会引⼊延时

oducer所使⽤的压缩器,⽬前⽀持gzip,snappy和lz4。压缩是在⽤户主线程完成的,通常都需要花费⼤量的CPU时间,但

对于减少⽹络IO来说确实利器。⽣产环境中可以结合压⼒测试进⾏适当配置

tion关乎消息乱序的⼀个配置参数。它指定了Sender线程在单个Socket连接上能够发送未应答PRODUCE请求

的最⼤请求数。适当增加此值通常会增⼤吞吐量,从⽽整体上提升producer的性能。不过笔者始终觉得其效果不如调节来得明显,所

以请谨慎使⽤。另外如果开启了重试机制,配置该参数⼤于1可能造成消息发送的乱序(先发送A,然后发送B,但B却先⾏被broker接收)

retries重试机制,对于瞬时失败的消息发送,开启重试后KafkaProducer会尝试再次发送消息。对于有强烈⽆消息诗经爱情诗的情感内涵 丢失需求的⽤户来

说,开启重试机制是必选项。

内部原理

上⾯的那张图中其实并没有深⼊展开producer的⼯作原理。这⾥笔者打算详细说说Producer内部到底是如何⼯作的,也就是梳理⼀下当⽤户调⽤

(ProducerRecord,Callback)时Kafka内部都发⽣了什么事情。

Step1:序列化+计算⽬标分区

这是KafkaProducer#send逻辑的第⼀步,即为待发送消息进⾏序列化并计算⽬标分区,如下图所⽰:

如上图所⽰,⼀条所属topic是\"test\",消息体是\"message\"的消息被序列化之后结合KafkaProducer缓存的元数据(⽐如该topic分区数信息等)共同传给后

⾯的Partitioner实现类进⾏⽬标分区的计算。

Step2:追加写⼊消息缓冲区(accumulator)

producer创建时会创建⼀个默认32MB(由参数指定)的accumulator缓冲区,专门保存待发送的消息。除了之前在“关键参数”段落中提到

的和等参数之外,该数据结构中还包含了⼀个特别重要的集合信息:消息批次信息(batches)。该集合本质上是⼀个HashMap,⾥

⾯分别保存了每个topic分区下的batch队列,即前⾯说的批次是按照topic分区进⾏分组的。这样发往不同分区的消息保存在对应分区下的batch队列

中。举个简单的例⼦,假设消息M1,M2被发送到test的0分区但属于不同的batch,M3分送到test的1分区,那么batches中包含的信息就是:{\"test-0\"-

>[batch1,batch2],\"test-1\"->[batch3]}

单个topic分区下的batch队列中保存的是若⼲个消息批次。每个batch中最重要的3个组件包括:

compressor:负责执⾏追加写⼊操作

batch缓冲区:由参数控制,消息被真正追加写⼊到的地⽅

thunks:保存消息回调逻辑的集合

这⼀步的⽬的就是将待发送的消息写⼊消息缓冲池中,具体流程如下图所⽰:

okay!这⼀步执⾏完毕之后理论上讲⽅法就执⾏完毕了,⽤户主线程所做的事情就是等待Sender线程发送消息并执⾏返回结果

了。

Step3:Sender线程预处理及消息发送

此时,该Sender线程登场了。严格来说,Sender线程⾃KafkaProducer创建后就⼀直都在运⾏着。它的⼯作流程基本上是这样的:

1.不断轮询缓冲区寻找已做好发送准备的分区

2.将轮询获得的各个batch按照⽬标分区所在的leaderbroker进⾏分组

3.将分组后的batch通过底层创建的Socket连接发送给各个broker

4.等待服务器端发送response回来

为了说明上的⽅便,我还是基于图的⽅式来解释Sender线程的⼯作原知止不殆是什么意思 理:

Step4:Sender线程处理response

上图中Sender线程会发送PRODUCE请求给对应的broker,broker处理完毕之后发送对应的PRODUCEresponse。⼀旦Sender线程接收到response

将依次(按照消息发送顺序)调⽤batch中的回调⽅法,如下图所⽰:

做完这⼀步,producer发送消息就可以算作是100%完成了。通过这4步我们可以看到新版本producer发送事件完全是异步过程。因此在调优producer

前我们就需要搞清楚性能瓶颈到底好诗摘抄 是在⽤户主线程还是在Sender线程。具体的性能测试⽅法以及调优⽅法以后有机会的话我再写⼀篇出来和⼤家讨

论。

基本使⽤

由于KafkaProducer是线程安全的,因此在使⽤上有两种基本的使⽤⽅法:

说明优势劣势

KafkaProducer

实例

所有线程共享⼀个

KafkaProducer实例

实现简单,性能好

1.所有线程共⽤⼀个内存缓存池,可

能需要较多的内存空间

2.⼀旦崩溃所有⽤户线程都⽆法⼯作

KafkaProducer

实例

每个线程维护⼀个

KafkaProducer实例

1.每个⽤户线程拥有专属的KafkaProducer实例、缓冲区空间

以及⼀组配置参数,⽀持细粒度化调优

2.单个KafkaProducer崩溃不会影响其他producer⼯作

较⼤的对象分配开销

总结

最后简单总结⼀下,本⽂主要讨论了新版本producer的⼀些设计特点及基本的使⽤⽅法。再次强调⼀下,新版本的producer使⽤完全异步化的多线程

处理⽅立秋的句子发朋友圈 式,同时结合分批处理机制,极⼤地提升了整体的性能。由于⽬前Kafka社区早已不维护Scala版producer了,所以还在使⽤0.8.2.x版本的⽤户

有条件的话尽量还是升级到最新的Kafka版本吧。

更多推荐

producer是什么意思ducer在线翻译读音例