深入Kafka -生产者客户端

生产者客户端有两个线程协调运行,分别是 主线程Sender线程 。主线程负责创建消息、序列化消息以及为消息分区等工作,由KafkaProducer、拦截器、序列化器、分区器、消息累加器组成;Sender负责发送消息,由Sender、InFlightRequest、Selector。
深入Kafka -生产者客户端_第1张图片

1. KafkaProducer

//设置客户端参数
Properties properties = new Properties();
properties.put(“key.serializer”,“org.apache.kafka.common.serialization.StringSerializer”);
properties.put(“value .serializer”, “org.apache.kafka.common.serialization.StringSerializer”);
properties.put(“bootstrap.servers”,brokerList);
//创建KafkaProducer实例
KafkaProducer producer = new KafkaProducer<>(properties);
//构建所需妥发送的消息
ProducerRecord record = new ProducerRecord<>(topic,“hello, Kafka!”);
//发送消息
producer.send(record) ;

2. 拦截器(非必须)

生产者拦截器既可以用来在消息发送前做一些准备工作,比如按照某个规则过滤不符合要求的消息、修改消息的内容等,也可以用来在发送回调逻辑前做一些定制化的需求,比如统计类工作。

3. 序列化器

生产者需要用序列化器(Serializer)把对象转换成字节数组才能通过网络发送给 Kafka 。而在对侧,消费者需要用反序列化器(Deserializer)把从 Kafka 中收到的字节数组转换成相应的对象。

4. 分区器

消息经过序列化之后就需要确定它发往的分区,如果消息 ProducerRecord(下文简称 Record)中指定了partition字段,那么就不需要分区器的作用,因为 partition 代表的就是所要发往的分区号。如果消息 Record 中没有指定 partition 字段,那么就需要依赖分区器, 根据key这个字段来计算 partition 的值。分区器的作用就是为消息分配分区。

5. 消息累加器

累加器用来缓存消息以便 Sender线程批量发送。缓存大小通过客户端参数 buffer.merory 配置,默认32M。

  1. ProducerBatch(下文简称Batch)
    Batch 是一批 Record,包含至少一个 Record,这样可以使字节更紧凑,从而达到减少请求次数和提高网络吞吐量的目的。
  2. 消息写入累加器的过程:
    2.1 根据 Record 的 partition 找到分区对应的双端队列(没有就创建),从中取出队尾 Batch(没有就创建);
    2.2 检查 Batch 中是否有足够空间写入该 Record,如果可以则写入,流程结束;
    2.3 如果空间不够,则判断 Record 的大小是否超过 batch.size(默认16k),如果不超过则通过客户端内存管理获得内存创建 Batch,否则申请相应大小的内存创建 Batch;
    2.4 将 record 写入;
  3. 客户端内存管理:
    为了优化内存分配,客户端实现 BufferPool 进行内存管理,BufferPool 会根据 batch.size 的大小动态创建内存块,避免内存的频繁创建和释放。

6. Sender

Sender 从累加器中获取缓存的消息之后,会进一步将原本 <分区,Deque< ProducerBatch>> 的保存形式转变成 的形式,其中 Node 表示 Kafka 集群的 broker 节点。
在转换成 > 的形式之后,Sender 还会进一步封装成 的形式,这样就可以将 Request 请求发往各个Node了,这里的 Request 是指Kafka的各种协议请求,对于消息发送而言就是指具体的 ProduceRequest 。1

7. InFlightRequest

InFlightRequests保存对象的具体形式为 Map>,它的主要作用是缓存了已经发出去但还没有收到响应的请求(Nodeld是一个String类型,表示节点的id编号)。通过 Deque< Request>的 size,可以判断对应的Node节点是否过载,从而限制向其发送消息,达到负载均衡的目的;除此之外,还可据此得出负载最小的 Node,元数据的更新请求便可发到该Node,完成元数据更新

元数据是指Kafka集群的元数据,这些元数据具体记录了集群中有哪些主题,这些主题有哪些分区,每个分区的leader副本分配在哪个节点上,follower副本分配在哪些节点上,哪些副本在AR、ISR等集合中,集群中有哪些节点,控制器节点又是哪一个等信息。

元数据的更新是在客户端内部进行的,由Sender线程在 1)客户端找不到对应的元数据信息(如找不到topic)或 2)超过 metadata.max.ago.ms 时间没更新(默认5分钟)时发起。

8. Selector

处理网络连接与读写处理。2


  1. 详见 – 【深入Kafka - 服务端】 ↩︎

  2. 参考 Kafka原理你真的知道吗?-- 3.5网络模型 ↩︎

你可能感兴趣的:(kafka)