log4j2与Kafka结合使用效果不佳

时间:2016-12-12 15:43:01

标签: java apache-kafka log4j2

我使用log4j2(2.5)与Kafka(0.10.1.0)结合使用会遇到性能问题。当我在log4j2.xml文件中启用Kafka时,我的应用程序变慢为爬行,同时仅向Kafka代理输出大约200KB / s的事件。这比卡夫卡应该达到的要低几个数量级(https://engineering.linkedin.com/kafka/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines)。

以下是我的log4j2.xml配置文件的相关部分:

<Kafka name="KafkaAll" topic="all">
  <PatternLayout pattern="%date %message" />
  <Property name="bootstrap.servers">localhost:9092</Property>
  <Property name="buffer.memory">67108864</Property>
  <Property name="batch.size">8196</Property>
  <Property name="acks">1</Property>
</Kafka>

经过一些测试后,我已经能够解决问题,并发现Kafka附带的ProducerPerformance测试确实取得了不错的性能。它的性能大约为5MB / s,具有类似大小的100字节消息。经过大量测试后,我发现差异不在于配置,而在于调用的实现方式。 log4j2 KafkaAppender使用KafkaManager类将日志写入Kafka:

public void send(final byte[] msg) throws ExecutionException, InterruptedException, TimeoutException {
    if (producer != null) {
        producer.send(new ProducerRecord<byte[], byte[]>(topic, msg)).get(timeoutMillis, TimeUnit.MILLISECONDS);
    }
}

性能问题是由于调用&#34; get&#34;方法,阻止直到发送完成。有趣的是,Kafka附带了一个log4j appender确实考虑了这个问题:

Future<RecordMetadata> response = producer.send(new ProducerRecord<byte[], byte[]>(topic, message.getBytes()));
if (syncSend) {
    try {
        response.get();
    } catch (InterruptedException ex) {
        throw new RuntimeException(ex);
    } catch (ExecutionException ex) {
        throw new RuntimeException(ex);
    }
}

换句话说,当syncSend设置为false时,对send的调用立即返回。这个&#34; syncSend&#34;但是,在KafkaAppender的log4j2实现中找不到属性。

我尝试通过其他方式异步调用,例如使用log4j2附带的AsyncAppender并将acks属性设置为0而不是1.但是,没有设置通过不等待来获得性能提升发送完成。我也尝试使用Kafka附带的log4j appender,但我没有设法使用log4j2(我想坚持使用log4j2)。

所以,最后,我决定将log4j2附带的KafkaAppender分叉并删除阻塞部分。这有效,但我当然更喜欢使用现成的包装。

有没有人也遇到过这个问题?你是怎么解决这个问题的?没有更改代码有更简单的方法吗?

1 个答案:

答案 0 :(得分:3)

KafkaAppender现在有一个新属性&#34; syncSend&#34;可以设置为支持异步发送,显着提高Kafka的吞吐量。感谢您的支持!

相关问题