kafka 生产者源码分析(一)- 生产者发送消息过程

基于kafka 0.10版本源码分析   

早期kafka 0.8.22,0.9.X 版本kafka 生产者消费者服务端都是用scala编写。而且放在cores包下,新版本的客户端使用java实现,放在clients包下。

     新的生产者客户端是一个进程,使用KafkaProducer对象实例化。这个生产者客户端,不直接发送消息给服务端,而是使用了一个名叫 RecordAccumulator队列收集要发送的消息,然后有个叫Sender的发送线程读取RecordAccumulator的消息,批量发送。

     为了保证生产者客户端网络请求的快速响应,客户端使用了NIO的选择器selector,处理网络连接和读写。而网络连接NetworkClient处理网络请求。

源码就不粘贴出来了,纯文字手打记录自己的理解。

当我们调用了producer的send方法后,打开源码看,send方法调用了doSend方法,首先总结producer doSend都做了哪些操作:

1、序列化,key、value的序列化。

2、分区,给消息体producerRecord分配要发送的topic 分区号。

3、进入收集器,加入到消息收集器RecordAccumulator当中、最后是判断是否要发送。这个加入消息收集器,首先得从Deque里找到自己的目标分区,如果没有就新建一个批量消息deque加进入。

4、如果达到发送阈值,唤醒发送线程,将batch record转换成request client 的发送消息体。

5、将发送请求放入发送队列。

6、如果上一个发送请求没完成,不会新建发送请求。

7、发送请求后,会附带callback回调函数。依赖配置,服务端会发回发送完成的响应、接收完成的响应给client端。

kafka发送数据请求给服务端后,服务端首先会确认返回,你的请求我收到了,返回的就是发送完成请求completeSend;当服务端将请求写入磁盘完成相关的副本同步,就返回接收完成的响应completeReceived.

   在第三步骤,消息是按分区进行分组写入batch record里的,在5的时候,就会将同一个node节点的分区信息合并为一条发送请求。这样可以提高发送效率,减少建立发送client 的次数。比如分区数量有10个,节点只有5个。那么如果消息按节点发送只需要发送5次,如果按照分区发送,需要发送10次。效率就不高了。

 

1、消息收集器,RecordAccumulator。

1.1 生产发送消息同步和异步的区别

      

你可能感兴趣的:(Kafka)