Apache Kafka-越来越多的消费者反复使用

时间:2018-11-24 20:44:24

标签: java apache-kafka kafka-consumer-api

上下文

我们正在使用Kafka处理大消息,偶尔会达到10MB,但大部分在500KB范围内。处理一条消息可能需要大约30秒,但有时需要一分钟。

问题

使用较少数量的使用者(最多约50个)处理数据不会导致经纪人重复进行重新平衡,并且处理工作正常。这种规模的任何重新平衡也相当快,根据经纪人的记录,通常不到一分钟。

一旦将消费者缩放到100或200,消费者就会不断重新平衡,间隔时间最多为5分钟左右。这导致工作/消耗5分钟,然后重新平衡5分钟,然后再次保持平衡。消费者服务不会失败,只要没有真正明显的原因就可以重新平衡。扩大消费者数量时,这会导致吞吐量降低。

当扩展到2oo个使用者时,该处理平均每位使用者每分钟2条消息的速度执行。单个使用者不重新平衡时的处理速度约为每分钟6条消息。

我不怀疑数据中心的网络是一个问题,因为我们有一些消费者对消息进行不同类型的处理,他们没有问题,每分钟将100到1000条消息传递。

其他人是否经历过这种模式并找到了简单的解决方案,例如更改特定的配置参数?

其他信息

Kafka代理为2.0版,其中有10个位于不同的数据中心。复制设置为3。此主题的分区为500。特定代理配置的摘录,以更好地处理大型邮件:

  • compression.type = lz4
  • message.max.bytes = 10000000#10 MB
  • replica.fetch.max.bytes = 10000000#10 MB
  • group.max.session.timeout.ms = 1320000#22分钟
  • offset.retention.minutes = 10080#7天

消费者端,我们将Java客户端与重新平衡监听器结合使用,该监听器可以清除已撤销分区中的所有缓冲消息。该缓冲区是10条消息。使用者客户端运行客户端API版本2.1,将Java客户端从2.0更新到2.1似乎可以在这些较大的使用者数量上显着减少以下类型的代理日志(我们几乎为每个客户端和每次重新平衡都获得了此类日志):

INFO [GroupCoordinator 2]: Member svc002 in group my_group has failed, removing it from the group (kafka.coordinator.group.GroupCoordinator)

消费者与经纪人位于不同的数据中心。偏移的提交是异步执行的。循环轮询在线程中执行,该线程以15秒的超时填充缓冲区。一旦缓冲区已满,线程将休眠几秒钟,并且仅在缓冲区具有可用空间时才轮询。较大消息用例的配置摘录:

  • max.partition.fetch.bytes.config = 200000000#200 MB
  • max.poll.records.config = 2
  • session.timeout.ms.config = 1200000#20分钟

日志文件

以下是代理日志文件的摘录,该日志在30分钟的时间范围内管理此特定组。命名简化为my_group和mytopic。也有一些无关主题的条目。

19:47:36,786] INFO [GroupCoordinator 2]: Stabilized group my_group generation 3213 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
19:47:36,810] INFO [GroupCoordinator 2]: Assignment received from leader for group my_group for generation 3213 (kafka.coordinator.group.GroupCoordinator)
19:47:51,788] INFO [GroupCoordinator 2]: Preparing to rebalance group my_group with old generation 3213 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
19:48:46,851] INFO [GroupCoordinator 2]: Stabilized group my_group generation 3214 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
19:48:46,902] INFO [GroupCoordinator 2]: Assignment received from leader for group my_group for generation 3214 (kafka.coordinator.group.GroupCoordinator)
19:50:10,846] INFO [GroupMetadataManager brokerId=2] Removed 0 expired offsets in 0 milliseconds. (kafka.coordinator.group.GroupMetadataManager)
19:54:29,365] INFO [GroupCoordinator 2]: Preparing to rebalance group my_group with old generation 3214 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
19:57:22,161] INFO [ProducerStateManager partition=unrelated_topic-329] Writing producer snapshot at offset 88002 (kafka.log.ProducerStateManager)
19:57:22,162] INFO [Log partition=unrelated_topic-329, dir=/kafkalog] Rolled new log segment at offset 88002 in 11 ms. (kafka.log.Log)
19:59:14,022] INFO [GroupCoordinator 2]: Stabilized group my_group generation 3215 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
19:59:14,061] INFO [GroupCoordinator 2]: Assignment received from leader for group my_group for generation 3215 (kafka.coordinator.group.GroupCoordinator)
20:00:10,846] INFO [GroupMetadataManager brokerId=2] Removed 0 expired offsets in 0 milliseconds. (kafka.coordinator.group.GroupMetadataManager)
20:02:57,821] INFO [GroupCoordinator 2]: Preparing to rebalance group my_group with old generation 3215 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
20:06:51,360] INFO [GroupCoordinator 2]: Stabilized group my_group generation 3216 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
20:06:51,391] INFO [GroupCoordinator 2]: Assignment received from leader for group my_group for generation 3216 (kafka.coordinator.group.GroupCoordinator)
20:10:10,846] INFO [GroupMetadataManager brokerId=2] Removed 0 expired offsets in 0 milliseconds. (kafka.coordinator.group.GroupMetadataManager)
20:10:46,863] INFO [ReplicaFetcher replicaId=2, leaderId=8, fetcherId=0] Node 8 was unable to process the fetch request with (sessionId=928976035, epoch=216971): FETCH_SESSION_ID_NOT_FOUND. (org.apache.kafka.clients.FetchSessionHandler)
20:11:19,236] INFO [GroupCoordinator 2]: Preparing to rebalance group my_group with old generation 3216 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
20:13:54,851] INFO [ProducerStateManager partition=mytopic-321] Writing producer snapshot at offset 123640 (kafka.log.ProducerStateManager)
20:13:54,851] INFO [Log partition=mytopic-321, dir=/kafkalog] Rolled new log segment at offset 123640 in 14 ms. (kafka.log.Log)
20:14:30,686] INFO [ProducerStateManager partition=mytopic-251] Writing producer snapshot at offset 133509 (kafka.log.ProducerStateManager)
20:14:30,686] INFO [Log partition=mytopic-251, dir=/kafkalog] Rolled new log segment at offset 133509 in 1 ms. (kafka.log.Log)
20:16:01,892] INFO [GroupCoordinator 2]: Stabilized group my_group generation 3217 (__consumer_offsets-18) (kafka.coordinator.group.GroupCoordinator)
20:16:01,938] INFO [GroupCoordinator 2]: Assignment received from leader for group my_group for generation 3217 (kafka.coordinator.group.GroupCoordinator)

非常感谢您提供有关此问题的帮助。

1 个答案:

答案 0 :(得分:0)

经过进一步的工程和微调,我们设法控制了该问题。

首先,似乎某些服务的处理仍超出限制,这导致它们很少失败。接下来的离开导致重新平衡,然后在大约6-7分钟后加入,这也导致重新平衡。通过在吞吐量方面优化服务,我们进一步降低了这一点。

第二个因素是我们用来扩展服务的底层Docker网络。默认情况下,心跳间隔非常短(5秒),因此,使用方节点上的任何艰苦工作和网络负载都可能在很短的间隔内将其从docker群中删除。 docker通过将这些服务移动到其他节点(重新平衡)来解决此中断,然后在节点重新联机时重新平衡。由于服务的启动时间很长,为5-7分钟,因此每次这些事件都需要重新平衡几次。

第三个因素是消费服务中的错误,导致其中一个偶尔崩溃,例如每小时1%。这又导致两次重新平衡,一次离开,一次加入。

总的来说,这些问题共同导致了所观察到的问题。最新的Kafka版本似乎还输出有关为什么服务离开消费者群体的更多信息。如果Kafka继续向仍然稳定的消费者提供数据,那就太好了,我可能会为此添加功能请求。尽管如此,我们现在仍能以稳定的性能运行稳定。