这是我参与更文挑战的第8天,活动详情查看:更文挑战
首先开发者,开启一个 producer,是在 JVM 上开了一个线程。如果你要多开几个 producer,每个线程都会分配一个 client id: producer-1。然后在发送消息到 broker 进过了哪些组件。
组件概览
拦截器 -> Partitioner -> 序列化器/反序列化器 -> metadata -> RecordAccumulator -> Sender -> NetworkClient
Partitioner:发送的消息会通过一定的分区规则路由到订阅的topic的某一个partitionmetadata:从broker集群获取topic的元数据 (Topic -> Partitions(Leader+Followers,ISR)),只有这样才知道到底有哪些partition可以发送。总之你的元数据发生变化,就会对这个产生影响RecordAccumulator:消息发送的缓冲区,发送到指定分区的消息会被打包成一个个batch。对于一个broker的多个分区的多个batch会被打包成一个request发送。batch控制参数:batch.size(调优参数在:this.accumulator = new RecordAccumulator()中的参数可以体现)Sender:负责从缓冲区里获取消息发送到 broker 上去NetworkClient:网络通信的组件,底层真正做发送的组件。被封在Sender里面KafkaThread:是实际发送数据的线程,name = kafka-producer-network-thread | clientId。在Sender被初始化时,这个线程就被启动起来了。
影响参数
metadata.max.age.ms:发送请求刷新broker topic元数据间隔时间,默认是:5分钟max.request.size:每个请求最大字节数限制,1Mbuffer.memory:消息缓冲区大小,32Mretry.backoff.ms:重试时间间隔,100msmax.block.ms:send()被阻塞的最大时间间隔 (原因:缓冲区阻塞/元数据信息不可用),默认 60srequest.timeout.ms:sender发送消息到broker的请求超时时间。默认 30sbatch.size:尽可能将 record 组装成 batch,减少IO。默认 16klinger.ms:当一个batch大小并没有完全凑出来,还是需要一个最小发送时间。默认是 0,也就是没有时间限制max.in.flight.requests.per.connection:同一个conn (对一个broker) 上的request最多有几个没收到响应,默认 5个acks:all 指leader+follower都要收到才能算这条消息写入成功,1 指leader写入就行。默认是 1retries:重试次数,默认是 0。如果你需要重试,可以设置