匹配卡夫卡消费者和生产者分区

问题描述:

我创建其中前端服务推消息到卡夫卡请求“主题并监听另一“响应”主题对于一些下游后端消费者(实际上是一个复杂的系统中的系统,该系统最终推回卡夫卡),对“请求”消息进行处理,最终推到“响应”主题。匹配卡夫卡消费者和生产者分区

我想弄清楚最优雅的方式,以确保消费者侦听适当的分区并接收响应,并且后端推到前端使用者正在侦听的分区。我们总是需要确保响应发送给产生初始消息的相同消费者。

我有两个解决方案,截至目前,但也不是特别令人满意。任何想法或想法将不胜感激:

  1. 有每个前端决定它将侦听哪个分区,并通过该消息传递给'request'主题的分区。当后端处理完成时,它将查看消息的分区成员并推送到相应的分区。这里最直接的问题是如何协调前端服务,以便每个分区具有均匀分布(随机分配?)。
  2. 每个消息具有相关性ID,一个GUID,所以为每个请求我们的前端,我们可以开始监听基于散列的GUID来分区的总数分区然后按消息发送到所述“请求”的主题。后端会查看关联ID以确定要推送到的适当分区。这里的一个问题是,对于每个请求,前端必须在新分区上建立新的使用者(这里是否有开销?),并且可能会在同一分区上有多个活动使用者,以及跨多个活动使用者许多分区。
  3. 有同等数量的消费者和分区的一个消费群,然后用类似的方法(1),但允许卡夫卡去应付这是消费者在哪个分区。但是,我们需要弄清楚重新平衡发生时会发生什么情况,特别是对于已经在后端运行的消息(因为可能所有分区都可能发生变化?)。

这似乎应该是一种常见的模式,所以我想知道别人怎么解决这个问题。

请不要使用消费者手动分配的分区。它会变得非常混乱,而且很难扩展。

而不是分区,您可以使用每个前端使用者的主题。每个前端服务都会生成一条消息,其中包含前端服务的标识request主题。然后后端消费该消息,并根据该id产生对特定unique-front-end-service-response主题的响应消息。 如果您有一个固定数量的前端服务,它可能是一个很好的解决方案。可能的缺点是每次您想添加新的前端服务时都会创建一个新的主题。但是,维护比手动分区分配要容易得多。

另一种可能的解决方案可能是使用不同的工具。如果卡夫卡不是强制性的,请重新考虑您的要求并进行研究。可能有一种工具比卡夫卡更适合您的需求。

+0

谢谢 - 每个前端的单个主题似乎可能是一个可行的解决方案。我们在后台大量使用Kafka,但我想我们总是可以找到与前端直接通信的其他方式,而不是在后端处理完成时通过Kafka进行通信。 – David

有时响应不回到原来的请求的应用程序,如果有可能直接通过发送卡夫卡响应消息到卡夫卡连接器,通过网络挂接,WebSocket的,现直接对外交货响应用户的请求,或短信回复原始用户。

如果你只是想做SOAP或REST风格的RPC,那么只需使用HTTP而不是Kafka,因为这是一种经过验证的模式。

+0

在我们的例子中,前端是一个HTTP服务,所以同一个实例需要响应我们后端返回的内容。 – David

+0

因此,以您的HTTP服务的URL作为密钥发布Kafka请求消息。当后端Kafka消费者想要发送响应时,它应该发布到具有与密钥相同的URL的响应主题。然后,HTTP/webhook的Kafka连接器将获取响应消息,并执行HTTP回发原始HTTP服务(可能在稍微修改了URL的响应中)。因此,从原始Web服务的角度来看,它是kafka请求/ http响应。如果您想一次支持多个请求,只需在URL中添加一个correlationID即可 –

一个优雅的方法是在后端制作者中使用分区功能,并使用手动分区分配assign使前端消费者只听有趣的分区。

更详细:

在前端生产,你生产的“请求”消息,“请求”话题之前,设置消息钥匙前端客户端ID(它需要独一无二)。

在后端消费,有没有必要做手工分区的分配,只是用subscribe认购的request话题。但值得注意的是,当您收到“请求”消息并处理该消息时,请不要丢失消息密钥并保存。因为它确定请求来自哪里。

在后端生产者中,当您完成请求过程时,您将生成一条回复消息,并将响应消息键设置为您保留在上面的前端客户端ID。你还需要定义一个分区函数(一个散列函数,将客户机ID映射到分区号)。使用分区功能做send()

在前端消费者中,您需要使用assgin()方法来侦听特定分区。但是如何知道应该听哪个分区?只需使用它的client-id(它将在同一个客户机上相同)和上面定义的相同散列函数来计算你应该听的分区号。