一个消费者对应多个表,或每个表有多个消费者

yfjy0ee7  于 2022-10-07  发布在  Apache
关注(0)|答案(1)|浏览(257)

我有一个Kafka主题,有数百万次销售活动。我有一个消费者,它在每条消息上都会将数据插入到4个表中:1是原始销售额,1是按产品类别(日期、产品类别、销售总和)按日期列出的销售额1是按日期列出的客户销售额(日期、客户ID、销售总和)1是地点(日期、位置ID、销售总和)按日期列出的销售额

我使用SQL数据库来存储我的数据,所以上面的操作是插入或更新操作。

我想知道,(I)在这4个表中插入1个消费者还是(Ii)4个消费者,每个消费者负责在每个表中插入会更好呢?

这里的最佳实践是什么?

谢谢

gmxoilav

gmxoilav1#

在我看来,你有三种不同的选择。无论如何,老实说,我个人会选择第三个。

1-一个[消费者-生产者]线程

在此场景中,您只有一个线程负责:

1-Reading from Kafka
2-Process/Store in I
3-Process/Store in II
4-Process/Store in III
5-Process/Store in IV

所有这些都是按顺序进行的,因为您只有一个同时使用和处理消息的线程。

kafka-->(read)-->(process 1)-->(process 2)-->(process 3)-->process(4)

在这种情况下,如果2到5个步骤中的任何一个步骤被“损坏”,处理速度在某个点上降低,您的整个过程将变慢。如此一来,Kafka主题的滞后将会增加,只要帖子没有在新消息到达Kafka之前完成第五步。

对我来说,这是关于性能和容错的禁忌

**2-四个[消费者-生产者]

这使用与第一个场景相同的范例:读取的线程也负责处理。

但是,多亏了消费者群体,你可以将整个过程并行化。创建4个不同的组,并将每个组分配给一个消费者。

  • 为简单起见,让我们只为每个客户组创建一个线程。*

在这个场景中,您可以看到以下内容:

CONSUMER CG1
1-Reading from Kafka
2-Process/Store in I

CONSUMER CG2
1-Reading from Kafka
2-Process/Store in II

CONSUMER CG3
1-Reading from Kafka
2-Process/Store in III

CONSUMER CG4
1-Reading from Kafka
2-Process/Store in IV
|-->consumer 1-->(process1)-->T1
  kafka|-->consumer 2-->(process2)-->T2
       |-->consumer 3-->(process2)-->T3
       |-->consumer 4-->(process4)-->T4

优点:每个线程负责有限数量的任务。这将有助于缓解每个消费群体的滞后。

此外,如果一些存储任务失败或性能下降,这不会影响其他三个线程:它们将继续自己从Kafka读取和处理。

**3.消费与处理解耦

在我看来,这是最好的可能解决方案。

你把阅读任务和处理任务分开。这样,例如,您可以启动:

  • 一个消费者线程**

这只是从Kafka读取消息并将其存储在内存中的队列中,或可从工作线程访问的类似结构中,仅此而已。只需继续阅读并将消息放入队列中。

  • X个工作线程**(本例中为4个)

这些线程负责获取消费者放入队列(或队列,取决于您希望如何编码)中的消息,并处理/存储每个表中的消息。

类似于:

|--> queue1 -----> worker 1 --> T1
  kafka--->consumer--(msg)--|--> queue2 -----> worker 2 --> T2
                            |--> queue3 -----> worker 3 --> T3
                            |--> queue4 -----> worker 4 --> T4

你在这里得到的是:并行化,处理和消费的脱钩。在这里,Kafka的滞后将在99%的时间里,0。

在这种方法中,队列是在一些工作进程被卡住时充当缓冲区的队列。其他整个系统(主要是Kafka)不会受到处理逻辑的影响。

请注意,即使Kafka也不会因为保留而开始延迟或可能丢失消息,必须监视内部队列,或正确配置以将队列中的延迟消息发送到死信队列,以避免消费者被卡住。

这来自KafkaConsumer javadoc,它更好地解释了每个范例的正反两面:

下面的简单图表显示了第三种方案的优势:

消费者线程只消耗。这避免了Kafka延迟、必须处理的数据延迟(请记住,这应该是接近实时的)以及由于保留而导致的消息丢失。

其他x个工作器负责实际的处理逻辑。如果其中一个线程出现故障,则不会影响其他使用者或辅助线程。

相关问题