kafka源码分析之producer

Producerclient

示例代码

Properties props = new Properties();
props.put("bootstrap.servers""localhost:9092");
props.put("client.id""DemoProducer");
props.put("key.serializer""org.apache.kafka.common.serialization.ByteArraySerializer");
props.put("value.serializer""org.apache.kafka.common.serialization.ByteArraySerializer");
producer new KafkaProducer<IntegerString>(props);
this.topic = topic;
this.isAsync = isAsync;

String messageStr = "Message_";
long startTime = System.currentTimeMillis();
if (isAsync) {

异步处理,这个过程需要定义一个回调函数来监听发送的消息的响应结果

 // Send asynchronously
  
producer.send(new ProducerRecord<byte[]byte[]>(topic,
      messageNo.getBytes()/*key*/,
      messageNo.getBytes()/*value*/),

      /*异步处理,回调函数*/

      new DemoCallBack(startTimemessageNomessageStr));
else 

同步处理,发送完成后,等待发送的响应结果。

// Send synchronously
  
try {
    producer.send(new ProducerRecord<IntegerString>(topic,
        messageNo.getBytes()/*key*/,
        messageNo.getBytes()/*value*/)).get();
    System.out.println("Sent message: (" + messageNo + ", " + messageStr + ")");
  catch (InterruptedException e) {
    e.printStackTrace();
  catch (ExecutionException e) {
    e.printStackTrace();
  }
}

 

关于异步处理的回调函数定义:

这个回调函数实现需要实现org.apache.kafka.clients.producer.Callback接口。

class DemoCallBack implements Callback 

 

并实现接口中的函数:

public void onCompletion(RecordMetadata metadataException exception) {

这里的startTime是发送这条消息时,生成回调函数时传入的消息发送的开始时间,

计算出来了这次发送这条消息共花的时间
  long elapsedTime = System.currentTimeMillis() - startTime;
  if (metadata != null) {

如果metadata信息不为空,表示消息添加成功,可以得到当前添加成功的消息的offset.
    System.out.println(
        "message(" key ", " message ") sent to partition(" 

           + metadata.partition() +
            "), " +
            "offset(" + metadata.offset() + ") in " + elapsedTime + " ms");
  else {

这种情况下,表示exception有值,也就是添加消息失败了,可以直接打印这个失败的消息的内容。
    exception.printStackTrace();
  }
}

 

Client端的生成与处理流程

生成KafkaProducer实例

1,首先看看KafkaProducer实例生成:

根据传入的properties配置信息,生成用于Producer的config实例。

this(new ProducerConfig(properties)nullnull);

 

2,解析必要的配置项:

2,1,配置项client.id,用于标记client端的一个编码值,默认值为producer-1。在同一个进程内,多个client端时,如果没有指定,默认根据1这个值向后增加。

2,2,配置项partitioner.class,配置用于producer写入数据时用于计算这条数据对应的partition的分配算子实例,这个实例必须是的Partitioner实现。实例初始化时会调用configure函数把配置文件传入进去,用于实例生成时使用,默认情况下分区算子是DefaultPartitioner。这个默认算子根据当前的key值进行murmur2 hash并与对应的topic的个数于模,如果key为null时,根据一个自增的integer的值与partition的个数取模.

2,3,配置项retry.backoff.ms,用于在向broker发送数据失败后的重试间隔时间,默认值为100ms

2,4,配置项metadata.max.age.ms,用于配置每个producer端缓存topic的metadata的过期时间,默认值为5分钟。配置上面的2,3,与2,4的配置,生成一个Metadata实例。

2,5,配置项max.request.size,用于配置每次producer请求的最大的字节数,默认值为1MB。

2,6,配置项buffer.memory,用于配置producer端等待向server发送的数据的缓冲区的大小,默认值为32MB。

2,7,配置项compression.type,默认值none,用于配置数据的压缩算法,默认为不压缩,可配置的值为none,gzip,snappy,lz4

2,8,配置项max.block.ms,用于配置send数据或partitionFor函数得到对应的leader时,最大的等待时间,默认值为60秒。

2,9,配置项request.timeout.ms,用于配置socket请求的最大超时时间,默认值为30秒。

 

3,生成record的累加器,这是一个用于对producer要发送的数据进行缓冲的实例:

this.accumulator new RecordAccumulator(

        config.getInt(ProducerConfig.BATCH_SIZE_CONFIG),
        this.totalMemorySize,
        this.compressionType,
        config.getLong(ProducerConfig.LINGER_MS_CONFIG),
        retryBackoffMs,
        metrics,
        time,
        metricTags);

 

3,1,RecordAccumulator实例需要的配置:

3,1,1配置项batch.size,用于批量提交的batch字节大小,默认值为16384。

3,1,2配置项linger.ms,这个配置与3,1,1配合使用,用于配置数据缓存的最大延迟时间,默认值0.

3,1,3依赖的其它配置项:2,6  2,7 2,3。

 

4,根据配置项bootstrap.servers,多个配置使用逗号分开,

生成用于socket请求的InetSocketAddress实例集合。

4,1并根据配置的broker的连接地址集合,生成Cluster的实例。把cluster实例更新到metadata的实例中。

 

5,生成NetworkClient实例,这个实例用于与各个broker进行socket通信,生成用于进行数据发送的Sender实例,并生成用于数据发送的KafkaThread线程并启动。

 

6,根据配置项key.serializer/value.serializer,生成key与value的序列化实例,这实例必须是Serializer的实现。

 

KafkaThread线程初始化

生成NetworkClient实例需要的配置项:

1,配置项connections.max.idle.ms,默认值为9分钟,用于设置连接最大的空闲时间,

2,配置项max.in.flight.requests.per.connection,默认值5,用于设置每个连接最大的请求个数

3,配置

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值