apache-flink - 如果我的 Flink 应用程序需要具有高并行接收器,最佳实践是什么?

标签 apache-flink

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

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

所以我的问题是,这种情况下的最佳实践是什么?

之前我使用过 Apache Storm。对于 Storm 应用程序,我需要指定工作线程数(槽)以及每个运算符的并行度。然而,可用槽位不需要至少与应用程序的最大并行度一样大,因此对于这个应用程序,我可以设置 2 个工作线程,为 Source 和 Map 设置 2 个并行度,为 Sink 设置 20 个并行度,这样就可以了。最终只需要 2 个槽位,每个槽位有 1 个源、1 个 map 和 10 个水槽 bolt 。我觉得这样既满足了高并行sink的需求,又很好地利用了资源(只有2个Map)。为什么人们要这样设计 Flink 并行性?还是我的理解有误?

最佳答案

几个选项及其背后的原因:

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

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

除了上面的第 2 点之外,这些方案的一个问题是,您将占用大量资源,这些资源在等待缓慢的外部 API 响应时大部分时间都处于空闲状态。另外,在 Flink 用户函数中执行阻塞/同步 I/O 是有问题的,因为 Flink 的运算符是单线程的,并且您可以通过这样做来阻止检查点等。

关于apache-flink - 如果我的 Flink 应用程序需要具有高并行接收器,最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65300028/

相关文章:

apache-flink - flink 如何处理早期事件?忽略或创建单独的窗口?

java - 从kafka到redis的flink管道

python - TensorFlow Extended (TFX) : Clarify Beam, Airflow 和 Kubeflow 使用

hadoop - Flink数据源迭代

java - 将 12000 个文件导入到一张表中

java - 如何使用 Apache Flink 删除 Cassandra 中的行?

state - flink MapState 的 TTL 是针对整个 MapState 实例还是针对 MapState 中的每个元素

java - Apache Flink 中通用模式转换的 InvalidTypesException

scala - AvroTypeException : Not an enum: MOBILE on DataFileWriter

scala - Flink Gelly - 创建图表时类型不匹配