我们希望降低在 GCP Dataflow 中运行特定 Apache Beam 管道 (Python SDK) 的成本。
我们构建了一个内存密集型 Apache Beam 管道,每个执行器上运行需要大约 8.5 GB RAM。当前正在加载一个大型机器学习模型进行转换DoFn.setup
方法,以便我们可以为数百万用户预先计算推荐。
现有的 GCP 计算引擎机器类型的内存/vCPU 比率要么低于我们的要求(每个 vCPU 最多 8 GB RAM),要么高于我们的比率(每个 vCPU 24 GB RAM):https://cloud.google.com/compute/docs/machine-types#machine_type_comparison https://cloud.google.com/compute/docs/machine-types#machine_type_comparison
我们已经使用 GCP 成功运行了该管道m1-ultramem-40
机器的种类。然而,硬件使用——以及因此的成本——并不是最优的。此机器类型的每个 vCPU 的 RAM 比率为 24 GB。当使用它来运行上述管道时,虚拟机使用了不到 36% 的可用内存 - 但正如预期的那样,我们为此付出了全部代价。
当尝试使用运行相同的管道时custom-2-13312
机器类型(2 个 vCPU 和 13 GB RAM),Dataflow 崩溃,并出现错误:
Root cause: The worker lost contact with the service.
在监控运行 Dataflow 作业的 Compute Engine 实例时,很明显它们内存不足。 Dataflow 尝试将模型加载到内存中两次 - 每个 vCPU 一次 - 但可用内存只够一次。
如果我们能够告知 Apache Beam/Dataflow 特定转换需要特定数量的内存,那么问题就可以解决。但我们没能找到实现这一目标的方法。
我们能想到的另一个解决方案是尝试更改每个 Compute Engine 虚拟机的数据流执行器的比率。这将使我们能够找到一个比率,在尊重管道内存要求的同时,我们会浪费尽可能少的 vCPU。在使用前面提到的custom-2-13312
机器类型,我们尝试使用以下配置运行管道:
--number_of_worker_harness_threads=1 --experiments=use_runner_v2
--experiments=no_use_multiple_sdk_containers --experiments=beam_fn_api
--sdk_worker_parallelism=1
使用 (1) 时,我们设法拥有单个线程,但 Dataflow 为每个虚拟机生成了两个 Python 执行器进程。这导致管道崩溃,因为当空间仅够一次时,尝试将模型加载到内存中两次。
使用 (2) 时,每个虚拟机生成一个 Python 进程,但它使用两个线程运行。每个线程都尝试加载模型,但虚拟机内存不足。
方法(3)与(1)和(2)的结果非常相似。
不可能组合多个这些配置。
是否存在一组(一组)配置可以让我们控制每个虚拟机的数据流执行器数量?
还有其他我们可能没有想到的降低成本的替代方案吗?