KafkaProducer是线程安全的。一个Producer可以给多个线程共用或利用池化技术供线程调用。
Producer发送消息本身是异步操作,有三种模式:
- fire-and-forget(发后即忘),性能高但不可靠
- sync(同步),性能低但可靠
- async(异步),利用回调函数了解消息发送结果
发送的消息是ProducerRecord对象, 有多个构造方法,topic和value是必须的,其它可选参数包括分区号,key,headers,时间戳等。Kafka利用MurmurHash2算法对key进行计算分区号,相同的key会落在同一个分区上。
Kafka生产者端的发送消息由两个线程协调完成,主线程和Sender线程。
- 主线程主要负责创建消息,通过拦截器、序列化器和分区器处理后缓存到消息累加器(RecordAccumulator);
- 消息累加器为每一个分区维护着一个双端队列(Deque),队列中的元素类型为ProducerBatch,ProducerBatch维护着多个ProducerRecord;
- ProducerBatch的大小和batch.size配置项有关,每次有新的ProducerRecord,会从对应的分区的Deque尾部取出ProducerBatch,如果空间满足则把ProducerRecord写入ProducerBatch,否则创建新的ProducerBatch并写入ProducerRecord;
- 其后,Sender线程从消息累加器中获取ProducerBatch,通过消息格式多次转换并缓存在InFlightRequests中,转换的目的是为了与具体broker节点通信,并发送消息到broker节点上;
- InFlightRequest缓存没响应的请求,每个连接最多只能缓存5个请求,超过这个数,消息不会发送,必须收到相应后才能继续发送。