我们有一个顶层,它仅接收消息并写入Kafka主题以进行后端处理。我们以很高的速率发送消息;每天我们处理10亿条消息。我们有一个线程池,该线程池接受消息并写入Kafka生产者实例。在这里,我仅创建了一个生产者(单个实例),该生产者在多个线程之间共享。
最近,我观察到90%的线程处于阻塞状态。我发现Kafka正在按顺序发送数据。 Kafka Java驱动程序的producer.send()
方法中存在一个同步块:
def send(messages: KeyedMessage[K,V]*) {
**lock synchronized {**
if (hasShutdown.get)
throw new ProducerClosedException
recordStats(messages)
sync match {
case true => eventHandler.handle(messages)
case false => asyncSend(messages)
}
}
}
文档说,我们不需要创建多个生产者实例;一个实例可以在多线程环境中共享。但是,我们该怎么做呢?还是我们应该更好地创建生产者实例池?
答案 0 :(得分:0)
之所以建议在线程之间共享发布者客户端,是因为它可以更好地进行批处理,因为消息是在分区级别进行批处理的。更好的批处理可以带来更好的压缩(如果启用)和更高的吞吐量。您可以考虑调整参数,例如缓冲存储器和linger.ms以及批处理大小,以优化吞吐量。 一种完成,然后您可以考虑添加多个生产者。 另外,如果主题的传入速率很高,请考虑增加主题的分区数。