文章链接:kafkaide.com/learn/how-m…
概述
在使用Kafka的时候,我们会遇到一些问题:
- 一个生产者对应多个topic,还是一个topic对应一个生产者
- 如果多个线程都使用各自生产者实例写入一个topic会怎么样?
- 写入topic时如何避免乱序写入(这里要分单个线程场景和多个线程场景,单个线程更多的是指使用kafka集群时,不同的分区可能会导致消息被分发到多个分区,进而导致乱序。 多个线程的场景下,因为一个线程顺序肯定不会乱,但是多个线程可能会导致消费的时候是[1,2,a,b,c,3]或许消费者期待的是[1,2,3,a,b,c]但是由于网络等原因导致顺序和期待的不一致)
什么是生产者
可以理解为生产者是一个将新记录写入kafka集群的实体。
每个生产者都可以任意的写入所有topic和partition,不同于消费者,我们并不会为生产者指定一个固定的topic或者partition。
生产者封装了一个重要的逻辑:他可以让具有相同key的消息分发到相同的分区,基于此,他可以保证消息按时间顺序写入某个分区。
用一个生产者向所有topic和分区写入消息。
大多数情况这可能都是最优选择。
批处理
在将数据发送至kafka集群之前,生产者会对被写入的消息进行分批(可能按大小,也可能按时间)。如果你使用 librdkafka,可以按照消息的数目进行分批。
当你使用一个生产者时,批处理可能会更高效。生产者会尝试将一个网络请求中所有的属于某个kafka节点的消息合并在一起,这个分批可以包含不同的topic和不同的分区。
网络链接
当只使用一个生产者时,kafka集群可能只需要每个节点和该生产者保持一个链接,对于大多数应用来说,这是最好的选择。
使用多个生产者不可避免的会产生更多的TCP链接,如果一定要使用的话需要从这个角度进行考虑。
多个生产者可能会导致消息的乱序
添加更多的生产者可能会在不同生产者写入相同key的消息时,消息乱序。因此如果一定要使用多个生产者,最好根据key分配不同的生产者实例。
为了扩大规模的最佳实践
kafka生产者是线程安全,所以如果你需要更好的性能,可以考虑多个线程共享一个生产者,这么做可以更快的进行分批(在按大小、数量分批时),同时也不会产生乱序。