匹配Kafka消费者和生产者分区
Matching Kafka consumer and producer partition
我正在创建一个系统,其中前端服务将消息推送到 Kafka 'request' 主题,并为一些下游后端消费者监听另一个 'response' 主题(实际上是一个复杂的系统,最终推回 Kafka) 对 'request' 消息进行处理并最终推送到 'response' 主题。
我正在尝试找出最优雅的方式来确保消费者在适当的分区上监听并接收响应,并且后端推送到前端消费者正在监听的分区.我们始终需要确保响应发送给生成初始消息的同一消费者。
目前我有两个解决方案,但都不是特别令人满意。任何想法或想法将不胜感激:
- 让每个前端决定它将监听哪个分区,并将该分区连同消息传递给 'request' 主题。当后端处理完成后,它会查看消息的分区成员并推送到适当的分区。这里的一个直接问题是如何协调前端服务,以便在每个分区上均匀分布(随机分配?)。
- 每条消息都有一个相关 ID,一个 GUID,因此对于我们前端的每个请求,我们可以开始侦听基于将 GUID 散列到分区总数的分区,然后将消息推送到 'request' 主题。然后后端会查看关联 ID 以确定要推送到的适当分区。这里的一个问题是,对于每个传入的请求,前端必须在新分区上建立一个新的消费者(这里有开销吗?)并且可能会在同一个分区上有多个活跃的消费者以及跨多个活跃的消费者许多分区。
- 有一个具有相同数量的消费者和分区的消费者组,然后采用与 (1) 类似的方法,但允许 Kafka 处理哪个消费者在哪个分区上。但是接下来我们需要弄清楚当重新平衡发生时会发生什么,特别是对于已经在后端传输的消息(因为所有分区都可能发生变化?)。
这似乎应该是一个常见的模式,所以我想知道其他人是如何解决这个问题的。
请不要使用手动分配分区的消费者。它会变得非常混乱,而且很难扩展。
您可以使用每个前端使用者的主题来代替分区。每个前端服务都会生成一条消息,其中包含 request
主题的前端服务 ID。然后后端使用消息并根据 id 生成对特定 unique-front-end-service-response
主题的响应消息。
如果您有固定数量的前端服务,这可能是一个很好的解决方案。可能的缺点是每次要添加新的前端服务时都会创建一个新主题。然而,它比手动分配分区更容易维护。
另一个可能的解决方案是使用不同的工具。如果 Kafka 不是强制性的,请重新考虑您的要求并进行研究。可能有比 Kafka 更适合您需求的工具。
有时,如果可以通过将 Kafka 响应消息发送到 Kafka 连接器来直接响应用户请求,则响应 没有 返回到原始请求应用程序通过 Webhooks、WebSocket、电子邮件或 SMS 文本消息将外部直接传送回原始用户。
如果您只想执行 SOAP 或 REST 样式的 RPC,那么只需使用 HTTP 而不是 Kafka,因为这是一种经过验证的模式。
一种优雅的方式是在后端生产者中使用分区函数,并使用手动分区分配assign
让前端消费者只监听感兴趣的分区。
更详细:
在前端生产者中,在向"request"主题生产"request"消息之前,将消息键设置为前端客户端id (它必须是唯一的)。
在后端consumer中,不需要手动分配分区,只需要使用subscribe
订阅request
主题即可。但值得注意的是,当您收到一条'request'消息并进行处理时,请不要丢失消息密钥,请妥善保管。因为它确定了请求的来源。
在后端生产者中,当你完成请求过程后,你生成一个响应消息来回复,并将响应消息键设置为前端客户端id你保留在上面。并且你还需要定义一个分区函数(一个散列函数,将一个客户端id映射到一个分区号)。使用分区函数做send()
.
在前端消费者中,需要使用assgin()
方法来监听具体的partition。但是如何知道应该监听哪个分区呢?只需使用它的 client-id(在同一个客户端上是相同的)和你在上面定义的相同的哈希函数来计算你应该监听的分区号。
我正在创建一个系统,其中前端服务将消息推送到 Kafka 'request' 主题,并为一些下游后端消费者监听另一个 'response' 主题(实际上是一个复杂的系统,最终推回 Kafka) 对 'request' 消息进行处理并最终推送到 'response' 主题。
我正在尝试找出最优雅的方式来确保消费者在适当的分区上监听并接收响应,并且后端推送到前端消费者正在监听的分区.我们始终需要确保响应发送给生成初始消息的同一消费者。
目前我有两个解决方案,但都不是特别令人满意。任何想法或想法将不胜感激:
- 让每个前端决定它将监听哪个分区,并将该分区连同消息传递给 'request' 主题。当后端处理完成后,它会查看消息的分区成员并推送到适当的分区。这里的一个直接问题是如何协调前端服务,以便在每个分区上均匀分布(随机分配?)。
- 每条消息都有一个相关 ID,一个 GUID,因此对于我们前端的每个请求,我们可以开始侦听基于将 GUID 散列到分区总数的分区,然后将消息推送到 'request' 主题。然后后端会查看关联 ID 以确定要推送到的适当分区。这里的一个问题是,对于每个传入的请求,前端必须在新分区上建立一个新的消费者(这里有开销吗?)并且可能会在同一个分区上有多个活跃的消费者以及跨多个活跃的消费者许多分区。
- 有一个具有相同数量的消费者和分区的消费者组,然后采用与 (1) 类似的方法,但允许 Kafka 处理哪个消费者在哪个分区上。但是接下来我们需要弄清楚当重新平衡发生时会发生什么,特别是对于已经在后端传输的消息(因为所有分区都可能发生变化?)。
这似乎应该是一个常见的模式,所以我想知道其他人是如何解决这个问题的。
请不要使用手动分配分区的消费者。它会变得非常混乱,而且很难扩展。
您可以使用每个前端使用者的主题来代替分区。每个前端服务都会生成一条消息,其中包含 request
主题的前端服务 ID。然后后端使用消息并根据 id 生成对特定 unique-front-end-service-response
主题的响应消息。
如果您有固定数量的前端服务,这可能是一个很好的解决方案。可能的缺点是每次要添加新的前端服务时都会创建一个新主题。然而,它比手动分配分区更容易维护。
另一个可能的解决方案是使用不同的工具。如果 Kafka 不是强制性的,请重新考虑您的要求并进行研究。可能有比 Kafka 更适合您需求的工具。
有时,如果可以通过将 Kafka 响应消息发送到 Kafka 连接器来直接响应用户请求,则响应 没有 返回到原始请求应用程序通过 Webhooks、WebSocket、电子邮件或 SMS 文本消息将外部直接传送回原始用户。
如果您只想执行 SOAP 或 REST 样式的 RPC,那么只需使用 HTTP 而不是 Kafka,因为这是一种经过验证的模式。
一种优雅的方式是在后端生产者中使用分区函数,并使用手动分区分配assign
让前端消费者只监听感兴趣的分区。
更详细:
在前端生产者中,在向"request"主题生产"request"消息之前,将消息键设置为前端客户端id (它必须是唯一的)。
在后端consumer中,不需要手动分配分区,只需要使用subscribe
订阅request
主题即可。但值得注意的是,当您收到一条'request'消息并进行处理时,请不要丢失消息密钥,请妥善保管。因为它确定了请求的来源。
在后端生产者中,当你完成请求过程后,你生成一个响应消息来回复,并将响应消息键设置为前端客户端id你保留在上面。并且你还需要定义一个分区函数(一个散列函数,将一个客户端id映射到一个分区号)。使用分区函数做send()
.
在前端消费者中,需要使用assgin()
方法来监听具体的partition。但是如何知道应该监听哪个分区呢?只需使用它的 client-id(在同一个客户端上是相同的)和你在上面定义的相同的哈希函数来计算你应该监听的分区号。