使用Scala的Kafka Producer无法进行批处理

使用Scala的Kafka Producer无法进行批处理,scala,apache-kafka,kafka-producer-api,Scala,Apache Kafka,Kafka Producer Api,我正在用Scala编写一个制作人,我想做批处理。批处理的工作方式是,它应该将消息保持在队列中,直到消息已满,然后将所有消息一起发布到主题上。但不知怎么的,它不起作用了。从我开始发送消息的那一刻起,它就开始一个接一个地发布消息。有人知道如何在Kafka Producer中使用批处理吗 val kafkaStringSerializer = "org.apache.kafka.common.serialization.StringSerializer" val batchSize: ja

我正在用Scala编写一个制作人,我想做批处理。批处理的工作方式是,它应该将消息保持在队列中,直到消息已满,然后将所有消息一起发布到主题上。但不知怎么的,它不起作用了。从我开始发送消息的那一刻起,它就开始一个接一个地发布消息。有人知道如何在Kafka Producer中使用批处理吗

val kafkaStringSerializer = "org.apache.kafka.common.serialization.StringSerializer"
      val batchSize: java.lang.Integer = 163840
      val props = new Properties()
      props.put("key.serializer", kafkaStringSerializer)
      props.put("value.serializer", kafkaStringSerializer)
      props.put("batch.size", batchSize);
      props.put("bootstrap.servers", "localhost:9092")

      val producer = new KafkaProducer[String,String](props)

      val TOPIC="topic"
      val inlineMessage = "adsdasdddddssssssssssss"

      for(i<- 1 to 10){
        val record: ProducerRecord[String, String] = new ProducerRecord(TOPIC, inlineMessage )
        val futureResponse: Future[RecordMetadata] =  producer.send(record)
        futureResponse.isDone
        println("Future Response ==========>" + futureResponse.get().serializedValueSize())
      }
val kafkstringserializer=“org.apache.kafka.common.serialization.StringSerializer”
val batchSize:java.lang.Integer=163840
val props=新属性()
props.put(“key.serializer”,KafkstringSerializer)
props.put(“value.serializer”,KafkstringSerializer)
道具放置(“批次大小”,批次大小);
props.put(“bootstrap.servers”,“localhost:9092”)
val producer=新卡夫卡制作人[字符串,字符串](道具)
val TOPIC=“TOPIC”
val inlineMessage=“ADSDASDDDSSSSS”

对于(i您必须在道具中设置
linger.ms

默认情况下,它为零,这意味着如果可能,消息将立即发送。 您可以增加它(例如100),以便批处理发生-这意味着更高的延迟,但更高的吞吐量

batch.size
是最大值:如果您在
linger.ms
之前到达它,数据将在不等待更多时间的情况下发送

要查看实际发送的批,您需要配置日志记录(批处理在后台线程上完成,您将无法查看使用producer api完成的批处理-您无法发送或接收批处理,只能发送记录并接收其响应,通过批处理与代理的通信在内部完成)

首先,如果尚未完成,请绑定一个log4j属性文件(
Dlog4j.configuration=file:path/to/log4j.properties

例如,我将收到

TRACE Sent produce request to 2: (type=ProduceRequest, magic=1, acks=1, timeout=30000, partitionRecords=({test-1=[(record=LegacyRecordBatch(offset=0, Record(magic=1, attributes=0, compression=NONE, crc=2237306008, CreateTime=1502444105996, key=0 bytes, value=2 bytes))), (record=LegacyRecordBatch(offset=1, Record(magic=1, attributes=0, compression=NONE, crc=3259548815, CreateTime=1502444106029, key=0 bytes, value=2 bytes)))]}), transactionalId='' (org.apache.kafka.clients.producer.internals.Sender)
这是一个包含2个数据的批处理。该批处理将包含发送给同一代理的记录

然后,使用batch.size和linger.ms查看差异。请注意,记录包含一些开销,因此batch.size为1000时不会包含10条大小为100的消息


注意,我没有找到说明所有记录器及其功能的文档(如log4j.logger.org.apache.kafka.clients.producer.internals.Sender)。您可以在rootLogger上启用调试/跟踪并找到所需的数据,或者同步地将数据生成到Kafka服务器。这意味着,当您使用
futuresponse.get
调用
producer.send
时,它将仅在数据存储到Kafka服务器后返回

将响应存储在单独的列表中,然后调用
futuresponse。在
for
循环之外获取

默认情况下,Kafka支持批处理,请参见
linger.ms
batch.size

List<Future<RecordMetadata>> responses = new ArrayList<>();
for (int i=1; i<=10; i++) {
    ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, inlineMessage);
    Future<RecordMetadata> response = producer.send(record);
    responses.add(response);
}

for (Future<RecordMetadata> response : responses) {
    response.get(); // verify whether the message is sent to the broker.
}
List responses=new ArrayList();

对于(inti=1;iI有。我有道具。put(“linger.ms”,5000)。但仍然不起作用。现在我看到我的消息延迟了5秒。消息仍然一条接一条地发送,但延迟了5秒。消息以批方式存储并以批方式获取,但它们仍然以单独消息的形式呈现给消费者。不要期望阅读单个消息并获得一批消息作为响应。这不是Kafka批处理的工作方式。因此,如果我必须验证我的批处理是否正确完成,我如何验证它?您可以查看代理上的JMX指标,它统计生成请求数和获取请求数。如果存在批处理,则请求数将低于消息数。另一种方法是be使用wireshark或其他网络数据包分析器查看卡夫卡请求和在线内容。
List<Future<RecordMetadata>> responses = new ArrayList<>();
for (int i=1; i<=10; i++) {
    ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, inlineMessage);
    Future<RecordMetadata> response = producer.send(record);
    responses.add(response);
}

for (Future<RecordMetadata> response : responses) {
    response.get(); // verify whether the message is sent to the broker.
}