【问题标题】:Optimizing a Kafka Streams Application with Multiple Sub-Topologies使用多个子拓扑优化 Kafka Streams 应用程序
【发布时间】:2018-07-05 23:19:57
【问题描述】:

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

  1. stream话题A
  2. selectKey 并重新分区主题 A to 主题 B
  3. stream话题B
  4. foreach 主题 B 到主题 C Producer
  5. stream话题C
  6. 话题Cto话题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 的比率,您如何确保每个线程都被分配了自己的主题分区并且某些线程不会闲置?

【问题讨论】:

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


    【解决方案1】:
    1. 线程将对不同子拓扑的所有主题进行 poll() 并检查记录 topic 元数据以将其提供给正确的任务。

    2. 每个子拓扑的处理方式相同,即,如果您愿意,可用资源均匀分布。

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

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

    几个通用的cmets:

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

    【讨论】:

    • 我的理解是max.poll.interval.ms默认设置为Integer.MAX_VALUE,应该是25天左右。我没有在我的配置中设置这个,但无论如何,消费者组在 25 天之前就被删除了。
    • 取决于您使用的版本。您可以在日志中仔细检查使用的值。
    • 重新回答 4:我发现这并不总是正确的(对于 1.1 版)。有时我必须重新启动流应用程序才能让所有线程拾取分区,但也许这应该是另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2023-01-09
    • 1970-01-01
    相关资源
    最近更新 更多