使用多个子拓扑优化Kafka Streams应用程序

时间:2018-07-05 23:19:57

标签: multithreading apache-kafka kafka-producer-api apache-kafka-streams

我正在运行具有三个子拓扑的Kafka Streams应用程序。活动阶段大致如下:

  1. stream主题A
  2. selectKey和分区主题A to主题B
  3. stream主题B
  4. foreach主题B至主题C Producer
  5. stream主题C
  6. 主题C to主题D

主题A,B和C均已实现,这意味着如果每个主题具有40个分区,则我的最大并行度为120。

起初,我运行5个流应用程序,每个应用程序具有8个线程。通过此设置,我遇到了不一致的性能。似乎有些共享同一线程的子拓扑比其他子拓扑更需要CPU,一段时间后,我会收到此错误:Member [client_id] in group [consumer_group] has failed, removing it from the group (kafka.coordinator.group.GroupCoordinator)。一切都会重新平衡,这可能会导致性能下降,直到下次出现故障并重新平衡为止。

我的问题如下:

  1. 如何在单个线程上运行多个子拓扑?投票队列?
  2. 每个线程如何决定如何将计算资源分配给每个子拓扑?
  3. 在这种情况下,如何优化线程与主题分区的比率,以避免出现周期性的使用者失败?例如1:1的比例是否可以确保性能更稳定?
  4. 如果您使用1:1的比率,如何确保为每个线程分配了自己的主题分区,并且确保某些线程不会闲置?

1 个答案:

答案 0 :(得分:1)

  1. 线程将对不同子拓扑的所有主题进行poll()并检查记录topic元数据以将其馈送到正确的任务中。

  2. 每个子拓扑都被视为相同,即,如果您愿意,可用资源将平均分配。

  3. 仅当您具有足够的内核时,1:1比率才有用。我建议监视您的CPU使用率。如果它太高(大于80%),则应添加更多的内核/线程。

  4. Kafka Streams会自动为您处理。

一般评论:

  • 您可能会考虑增加max.poll.interval.ms的配置,以避免消费者退出群组
  • 您可能会考虑减少max.poll.records来减少每次poll()调用的记录,从而减少两次连续调用poll()之间的时间。
  • 请注意,max.poll.records并不意味着增加网络/经纪人的通信-如果单个获取请求返回的记录多于max.poll.records配置,则数据将被缓冲在使用者和下一个{{ 1}}将从缓冲数据中提供,避免经纪人往返