我在使用 log4j2 (2.5) 和 Kafka (0.10.1.0) 时遇到了性能问题。当我在 log4j2.xml 文件中启用 Kafka 时,我的应用程序会变慢到爬行,同时只向 Kafka 代理输出大约 200KB/s 的事件。这比 Kafka 应该实现的目标低几个数量级(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>
Run Code Online (Sandbox Code Playgroud)
在运行一些测试之后,我已经能够确定问题并发现 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);
}
}
Run Code Online (Sandbox Code Playgroud)
性能问题是由调用“get”方法引起的,该方法会阻塞直到发送完成。有趣的是,Kafka 中包含一个 log4j appender,它确实考虑到了这个问题:
Future<RecordMetadata> response = …Run Code Online (Sandbox Code Playgroud)