Kafka Transactions:sendOffsetsToTransaction比sendRecord慢得多

时间:2018-10-22 10:54:00

标签: transactions apache-kafka kafka-producer-api

我正在计时一些事务代码,以查看我在哪里浪费的时间最多。 花费的时间是这样的 评论指出这是由于发送异步引起的。请继续阅读有关同步呼叫的后续问题。 (还是比较慢::)

producer.beginTransaction(); //0.08 ms
producer.sendOffsetsToTransaction( offsetMap, GROUP_ID);  // 105.96ms
producer.commitTransaction(); // 2.74ms


producer.beginTransaction(); //0.09 ms
producer.send(new ProducerRecord<byte[], byte[]>( "dev-null", payload ) );// 0.16 ms
producer.commitTransaction(); // 28.37 ms

计时是这样完成的:

long t0 = System.nanoTime();
statement_to_time();
long t1 = System.nanoTime();
long timeTaken = (t1-t0);

为什么在发送,sendOffsetsToTransaction和commitTransaction的时间上有如此明显的区别?

首先:dev-null__consumer_offsets都是具有50个分区的一式三份主题。

关注: 不能与send并行执行sendOffsetsToTransaction吗?我又跑了几次。 (注释是执行时间+提交时间):

// Asynchronous send. Flush cost is in commit call
producer.send(); // 0.16 ms + 28.36 ms 

// This call is Synchronous. Commit doesn't have flush cost 
producer.sendOffsetsToTransaction(...); // 105.9 ms + 2.7ms 

// Synchronous send. Flush cost is in the send.
producer.send(...).get() // 26.1ms + 2.4 ms

// flush is done with sendOffsetsToTransaction. Commit cost double for two partitions
producer.send(...); 
producer.sendOffsetsToTransaction(...);  // 128.26 ms + 5.40 ms 


// 5 partition write, no offset. commit cost is not 5x
producer.send(..., partition=0).get() ; 
producer.send(..., partition=1).get() ; 
...
producer.send(..., partition=4).get() ; // 28.3 ms + 2.52 ms

// 5 partition + offset write. commit cost is ~6x
producer.send(..., partition=0).get() ; 
producer.send(..., partition=1).get() ; 
...
producer.send(..., partition=4).get() ; 
producer.sendOffsetsToTransaction(...);  // 127.25 ms + 11.8 ms

我可以重新运行几次,但是到目前为止,kafka与数字保持一致。出现的新问题是:

  1. 为什么sendOffsetToTransaction仍然需要更长的时间(105ms vs 25ms)
  2. (不太明显)为什么可以并行执行多分区send(record),但是sendOffset是串行发送(record)的?同样,commit(transactionlog write)对于send(record)是并行的,但是对offset进行累加?
  3. 如果(2)为true,是否可以使用压缩主题来跟踪我自己的偏移量?我会错过什么?

0 个答案:

没有答案
相关问题