【问题标题】:What's the best practice if my Flink application needs to have a high parallel sink?如果我的 Flink 应用程序需要高并行接收器,最佳实践是什么?
【发布时间】:2020-12-15 23:43:25
【问题描述】:

假设我的 Flink 应用程序有 3 个组件:Source、Map 和 Sink。由于某些原因(例如调用 API 具有非常高的延迟),接收器需要具有非常高的并行度(例如 20)。还假设 Source 和 Map 占用很少的 CPU/IO。我们知道最小可用槽应该至少与应用程序的最大并行度一样大,在本例中为 20。部署此应用程序将有两种方式:

  1. 如果我已经有 Flink 集群,部署这个应用会占用 20 个 slot。但是,我的 Source 和 Map 不需要太多资源,所以这 20 个 slot 大部分时间都是空闲的(等待,因为 sink 调用 API 的延迟很高)。在这种情况下,我是在浪费资源。
  2. 我可以为此应用程序设置一个按作业集群,并将每个任务管理器的槽数设置得非常高,以减少每个槽的资源。在这种情况下,我还需要将 Map 的并行度设置为较高的值,以获得足够的 CPU 容量。但是,由于 Map 受 CPU 限制,高并行性会导致性能下降(线程上下文切换)。

所以我的问题是,在这种情况下,最佳做法是什么?

之前我使用的是 Apache Storm。对于 Storm 应用程序,我需要指定工作人员编号(插槽)和每个操作员的并行度。但是,可用slots不需要至少大到应用程序的最大并行度,所以对于这个应用程序,我可以设置2个worker,Source和Map设置2个并行度,Sink设置20个并行度,这样就可以了最终只占用 2 个插槽,每个插槽有 1 个源、1 个地图和 10 个 Sink bolts。我觉得这样既满足了高并行sink的需求,又能很好的利用资源(只有2个Map)。为什么人们要这样设计 Flink 并行性?还是我的理解有误?

【问题讨论】:

  • 在我的回答中,我假设这是一个流应用程序。如果是批处理,那么对话会有所不同。
  • 是的,它是一个流媒体应用
  • David 在下面使用选项#2 提出的建议在类似情况下对我们来说效果很好。您仍然需要以DiscardingSink 结尾,因此 Flink 对您拥有完整的工作流程感到满意,但所有有趣的调优/并行性都通过该接收器之前的 AsyncIO 函数发生。

标签: apache-flink


【解决方案1】:

几个选项,以及它们背后的原因:

  1. 在整个作业中使用 20 的并行度:源、映射、接收器。通过这样做,您可以利用operator chaining,并避免在映射和接收器之间进行序列化/反序列化和网络通信(并行度将从 2 变为 20)。您必须对其进行基准测试才能确定,但​​通常避免使用 ser/de 和网络堆栈可以节省大量资金。

  2. 在整个作业(包括接收器)中使用 2 的并行度,并使用异步客户端与外部 API 通信,以便每个接收器实例可以处理一堆并发请求。您可能可以使用 Flink 的 async i/o 来解决此问题,但如果这样做,您将不得不添加一个虚拟 sink(因为 Flink 坚持每个作业都有一个 sink)。

除了上面的 #2 之外,任何这些方案的一个问题是,您将占用大量资源,这些资源大部分时间都在等待缓慢的外部 API 响应时处于空闲状态。此外,在 Flink 用户函数中进行阻塞/同步 i/o 也是有问题的,因为 Flink 的操作符是单线程的,您可以通过这样做来阻塞检查点等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-10
    • 2011-09-19
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 2012-03-22
    相关资源
    最近更新 更多