我们正在努力使我们的Kafka用户并行处理更多数量的记录,以处理高峰负载。我们已经在做的一种方法是通过在同一个消费者组中分配尽可能多的消费者和分区。
到目前为止,我们的使用者处理的API调用是同步的。我们认为使此API调用异步将使我们的使用者处理更多的负载。因此,我们试图使API调用异步,并在响应中增加偏移量。但是,我们看到了一个问题:
通过使API调用异步,我们可以首先获取最后一条记录的响应,而之前尚未启动或完成以前的记录的API调用。如果我们在收到最后一条记录的响应后立即提交偏移量,则偏移量将更改为最后一条记录。同时,如果使用者重新启动或分区重新平衡,则在提交偏移量为的最后一条记录之前,我们将不会收到任何记录。这样,我们将错过未处理的记录。
到目前为止,我们已经有25个分区。我们期待了解是否有人在不增加分区或不增加分区的情况下实现了并行性,这是实现并行性的唯一方法(避免偏移问题)。
答案 0 :(得分:1)
首先,您需要将消息的读取与处理这些消息分开(如果仅是第一次)。接下来看一下您可以对API进行多少次并发调用,因为调用它比服务器能够处理的异步(无论是否异步)都没有任何意义。如果并发API调用的数量大致等于主题中分区的数量,则异步调用API没有任何意义。
如果分区数大大少于可能的并发API调用的最大数,那么您有几种选择。您可以按照建议的方式通过异步调用API来尝试以更少的线程(每个使用者一个)来最大程度地执行并发API调用,或者可以创建更多的线程并同步进行调用。当然,然后您会遇到一个问题,即您的消费者如何将他们的工作交给更多的共享线程,但这正是Flink或Storm这样的流执行平台为您服务的。提供检查点处理的流平台(例如Flink)还可以解决您在无序处理消息时如何处理偏移提交的问题。您可以滚动自己的检查点处理并滚动自己的共享线程管理,但是您实际上必须避免使用流式执行平台。
最后,您可能拥有比最大可能的并发API调用更多的使用者,但是我建议您只有较少的使用者和共享分区,而不是API调用线程。
当然,您始终可以更改主题分区的数量,以使上面的首选选项更加可行。
无论哪种方式,要回答您的特定问题,您都需要查看Flink如何使用Kafka偏移提交进行检查点处理。为了简化起见(因为我不希望您自己滚动),kafka使用者不仅要记住他们刚刚提交的偏移量,而且还必须保留以前提交的偏移量,并且定义了一组消息通过您的应用程序。整个消息块将一直处理到整个过程,或者您需要将每个线程的处理状态回滚到处理上一个块中最后一条消息的位置。同样,这是一个过分的简化,但这是完成的方式。
答案 1 :(得分:1)
您必须查看kafka batch
的处理过程。简而言之:您可以使用少量(甚至单个)batch.size
来设置庞大的partitions
。到目前为止,在batch
端(即在ram内存中)消耗了messages
的{{1}}中的整个consumer
-您可以按任意方式并行化此消息。
我真的很想分享链接,但是链接的数量遍布网络漏洞。
UPDATE
就提交偏移量而言-您可以对整个batch
执行此操作。
通常,kafka不会通过滥用分区号来达到目标性能要求,而是依靠batch
处理。
我已经看到了很多项目,它们受到分区扩展的影响(例如,稍后可能会在重新平衡期间看到问题)。经验法则-首先查看每个可用的batch
设置。