KafkaProducer原理解析

1. 生产者原理图

在这里插入图片描述

2. 概述

  • Producer客户端是由两个线程协调运行,主线程Sender线程
  • 主线程负责将消息发送到消息累加器[RecordAccumulator]中
  • RecordAccumulator缓存消息,以便消息可批量发送
  • Sender线程负责从RecordAccumulator中获取消息,并将消息发送到Kafka集群.

3. 原理解析

3.1 主线程

在主线程中,Producer生成消息后,经过拦截器[ProducerInterceptor]、序列化器[Serializer]、分区器[Partitioner]后将数据发送给RecordAccumulator

  • Producer

    负责生成消息

  • ProducerInterceptor

    Producer生成消息后,可以通过ProducerInterceptor对消息进行统一处理,不过一般很少用到到,因为我们可以在生成消息时就处理好,如果是涉及到了客户端监控、端到端系统性能检测、系统审计等功能在内的场景可以利用到拦截器

  • Serializer

    根据指定的序列化器将对象转化成字节数组存储到Kafka

    注意:生产者和消费者的序列化器必须是一一对应的关系,因为消费者是利用反序列化器将字节数组转换成对象.

  • Partitioner

    key进行哈希,根据哈希值计算分区,相同key的消息会被发送到相同的分区,默认的分区器是org che.kafka.clients.producer intemals.DefaultPartitioner.

3.2 RecordAccumulator

RecordAccumulator主要用以缓存消息,以批量的形式发送,可以有效减少网络IO的资源消耗以提升性能.

参数作用
buffer.memory默认33554432B配置RecordAccumulator的缓存大小
max.block.ms默认60000(60秒)当生产者发送消息的速度超过send将消息发送到服务器的速度时,会导致生产者空间不足,这时KafkaProducer.send方法会阻塞,当阻塞时间达到默认的60秒时会抛出异常.
  • Deque

    双端队列,在RecordAccumulator内部,为每个Partition维护了一个双端队列Deque<ProducerBatch>,消息写入时,追加到双端队列的尾部,读取消息时从头部开始读取.

  • ProducerBatch

    ProducerBatch是指一个消息的批次,Send从双端队列的尾部读取消息时,会将小的ProducerBatch合并成一个大的ProducerBatch,这样也会减少网络请求的次数以提升整体的吞吐量.

    当有消息[ProducereRedcord]流入到RecordAccumulator中时,会寻找该ProducerRecord对应分区的双端队列[Deque](如果Deque不存在则新建),然后从Deque尾部获取一个ProducerBatch(如果ProducerBatch没有则新建),判断该ProducerBatch是否还可以写入ProducerRecord,如果不可以则新建一个ProducerBatch

    参数作用
    batch.size默认值16KB用来设置batch.size的大小.当一个ProducerBatch的中的消息存满后,会根据新的ProducerRecord的大小进行判断,如果小于设置的batch.size的大小则根据batch.size新建一个ProducerBatch

3.3 Sender

SenderRecordAccumulator拉取到数据后,在将数据发送给Kafka集群,消息在RecordAccumulator中存储形式为<Partation,Deque<ProducerBatch>>,Sender将数据拉取过来后,数据形式变为<Node,List<ProducerBatch>>,Node代表Kafka集群的broker节点,而后Sender在将<Node,List<ProducerBatch>>进一步封装成<Node,Request>

  • InFlightRequests

    Sender线程在将请求发送到Kafka前会保存到InFlightRequests,数据保存形式为Map<NodeId,Deque<Request>>,NodeId代表brokerid编号.

    参数作用
    max.in.flight.request.per.connection默认值5管理客户端与Node之间的连接最多能缓存的未响应的请求数,超过该数值后,则不能向这个连接发送更多的请求
    max.request.size默认1048576B限制生产者发送消息的最大值
  • Request

    RequestKafka的各种协议请求,用以缓存已经发出但是还没有收到服务器端响应的请求.

  • Request

    RequestKafka的各种协议请求,用以缓存已经发出但是还没有收到服务器端响应的请求.

    可以通过<Deque<Reqquest>>sizemax.in.flight.request.per.connection参数的大小比较来判断对应的Node中是否已经堆积了很多未响应的消息,这样可以帮助我们判断Node是否存在负载过重或者网络连接存在问题.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值