Kafka Producer模块分析

1. 概述

一、Kafka Producer包含哪些部分
其实我们讨论producer时,指的是用户接触的clients.producer这个util包,其中包含了发送数据到哪台机器、怎样序列化、分批发送与拒绝消息等等的发送策略。
但这些讨论不包括Kafka接到这些消息后怎样处理的问题,这些是broker(即kafka server端)需要去处理的部分。
二、Producer与Broker的关系
producer会维护将要发送的topic表,在必要时向broker要这些topic的元信息,并在client端维护这些元信息,来决定每条消息的去向。
从broker角度来看,它提供了元信息给producer以后,就无法控制producer的行为了。可以这么理解——broker本身是无状态的机器,主要提供的是元信息的消息读写的接口。
三、Producer发送消息的流程简介

  1. 在发送消息时,等待元信息的更新
  2. 将key\value序列化为byte[],计算出数据的大小是否超出限制
  3. 计算出key对应的partition,以确认将消息发往哪里
  4. 使用accumulator将数据放到topic\partition对应的缓冲区中
  5. 使用NetworkClient类(背后是nio selector)定期的把缓冲区中的内容发出

注:本文基于Kafka 0.9版本,KafkaProducer的代码更新时间在2015-12-06

2. 字段与主要方法

2.1 KafkaProducer中的字段

    private static final AtomicInteger PRODUCER_CLIENT_ID_SEQUENCE = new AtomicInteger(1);

    private String clientId;                           // client.id参数:用于日志与打点,以及发请求带的参数
    private final Partitioner partitioner;        // partitioner.class参数:指定一个Partitioner类用于计算key对应的分片,可自定义
    private final int maxRequestSize;          // max.request.size参数:单条消息的内存byte数大于此值时,抛出RecordTooLargeException异常
    private final long totalMemorySize;        // buffer.memory参数:同上,但额外作为accumulator->BufferPool中的`The maximum amount of memory that this buffer pool can allocate`,似乎是accumulator中暂存消息最多可用的内存量。
    private final Metadata metadata;          // 维护了一些topic的元信息
    private final RecordAccumulator accumulator;    // 用于堆积消息,按情况batch发送
    private final Sender sender;      // 发送消息
    private final Thread ioThread;   // 把this.sender包装成一个Thread
    private final CompressionType compressionType;    //compression.type参数,压缩数据的方式,主要用在accumulator内。有none\gzip\snappy\lz4几种
    private final Metrics metrics;      // TODO 监控信息?
    private final Sensor errors;    // TODO 监控信息?
    private final Time time;          // KafkaProducer对象的创建时间
    private final Serializer<K> keySerializer;        // key序列化方法 
    private final Serializer<V> valueSerializer;    // value序列化方法
    private final ProducerConfig producerConfig;    // 外部把配置传入,但没多大用处
    private final long maxBlockTimeMs;      // 来源不明TODO,用处似乎是限制send的一些IO操作总时间(waitOnMetadata堵塞的时间,与accumulator.append中waitMemory堵塞的时间之和,要低于此值)
    private final int requestTimeoutMs;    //参数`timeout.ms` or `request.timeout.ms`,用途不明TODO

2.2 KafkaProducer提供的api

2.2.1 发送一条Kafka消息

public Future<RecordMetadata> send(ProducerRecord<K, V> record, Callback callback)
  1. 该方法做一定预处理后(详见第3节),将消息塞进accumulator缓冲区后,等待异步发送并返回,在消息实际发送完,即取到请求的返回值后,执行callback参数的回调方法。
  2. 返回体中包装的RecordMetadata类型,带有消息最终发到的partition与offset,可用future.get()堵塞到消息发送完成。
  3. 官方建议:由于callback会执行一个IO线程,因此建议处理速度足够快,否则会影响到其它线程。如果需要执行堵塞或计算量大的逻辑,建议另开一个Executor来并发处理callback来的数据。
  4. 可能抛出的异常:InterruptException(堵塞时被打断)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值