在Kafka文档中,提到使用者不是线程安全的。为避免此问题,我读到一个好主意,即为每个Java进程运行一个使用者。如何实现?
使用者的数量未定义,但可以根据需要进行更改。
谢谢, 阿莱西奥
答案 0 :(得分:1)
您是对的,该文档指定Kafka使用者不是线程安全的。但是,它也表示您应该在单独的线程上运行使用者, 不是过程。那是完全不同的。请参见此处,以获得针对Java / JVM的更具体的答案: https://stackoverflow.com/a/15795159/236528
通常,您可以在Kafka主题上拥有任意数量的消费者。其中一些共享一个组ID ,在这种情况下,该主题的所有分区将分布在任何时间点的所有活动使用者上。
有关卡夫卡消费者的Javadoc的更多信息,位于此答案的底部,但我复制了以下文档建议的两个线程/消费者模型。
1。每个线程一个消费者
一个简单的选择是为每个线程提供自己的使用者实例。这里 这种方法的优缺点:
PRO:这是最容易实现的
PRO:通常是最快的,因为不需要线程间协调
PRO:它使基于分区的有序处理非常容易实现(每个线程仅按接收消息的顺序处理消息)。
CON::更多使用者意味着与群集的TCP连接更多(每个线程一个)。通常,Kafka非常有效地处理连接,因此这通常是很小的成本。
CON :多个使用者意味着更多的请求被发送到服务器,而数据的批处理则略有减少,这可能会导致I / O吞吐量下降。
CON::所有进程中的线程总数将受分区总数的限制。
2。使消费与加工脱钩
另一种替代方法是让一个或多个消费者线程执行 所有数据消耗并将ConsumerRecords实例移交给 阻塞实际上由处理器线程池消耗的队列 处理记录处理。此选项同样具有优点和缺点:
PRO::此选项可独立扩展使用方数量 和处理器。这样就可以让一个消费者 提供许多处理器线程,避免了对分区的任何限制。
CON :要保证处理器之间的顺序需要特别注意 由于线程将独立执行,因此较早的数据块可能 实际上由于运气好而在后面的数据块之后被处理 线程执行时间。对于没有订购的处理 要求这不是问题。
CON :手动提交 位置变得越来越困难,因为它要求所有线程协调 确保该分区的处理完成。有许多 这种方法的可能变化。例如每个处理器 线程可以有自己的队列,使用者线程可以哈希到 这些队列使用TopicPartition来确保按顺序消费 并简化提交。
根据我的经验,选项#1最适合入门,只有在确实需要时才可以升级到选项#2。选项#2是从kafka用户中提取最大性能的唯一方法,但其实现更为复杂。因此,请先尝试选择#1,然后看一下是否足以满足您的特定用例。
完整的Javadoc可通过以下链接获得: https://kafka.apache.org/23/javadoc/index.html?org/apache/kafka/clients/producer/KafkaProducer.html