优化内存密集型数据流管道的 GCP 成本

2024-03-12

我们希望降低在 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机器类型,我们尝试使用以下配置运行管道:

  1. --number_of_worker_harness_threads=1 --experiments=use_runner_v2
  2. --experiments=no_use_multiple_sdk_containers --experiments=beam_fn_api
  3. --sdk_worker_parallelism=1

使用 (1) 时,我们设法拥有单个线程,但 Dataflow 为每个虚拟机生成了两个 Python 执行器进程。这导致管道崩溃,因为当空间仅够一次时,尝试将模型加载到内存中两次。

使用 (2) 时,每个虚拟机生成一个 Python 进程,但它使用两个线程运行。每个线程都尝试加载模型,但虚拟机内存不足。 方法(3)与(1)和(2)的结果非常相似。

不可能组合多个这些配置。

是否存在一组(一组)配置可以让我们控制每个虚拟机的数据流执行器数量?

还有其他我们可能没有想到的降低成本的替代方案吗?


我们正在研究这些问题的长期解决方案,但这里有一个战术修复方案,可以防止您在方法 1 和 2 中看到的模型重复:

跨工作线程共享虚拟机中的模型,以避免每个工作线程中重复模型。 使用以下实用程序(https://github.com/apache/beam/blob/master/sdks/python/apache_beam/utils/shared.py https://github.com/apache/beam/blob/master/sdks/python/apache_beam/utils/shared.py),Beam 2.24 中开箱即用 如果您使用的是 Beam 的早期版本,只需将 shared.py 复制到您的项目并将其用作用户代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

优化内存密集型数据流管道的 GCP 成本 的相关文章

随机推荐

  • 样式方面的
    或填充/边距元素

    现在有了 HTML5 和 CSS3 就是使用 br 当可以使用边距 填充时标签会皱起眉头 编辑 这是关于我的用例的 div 元素之间的间距 但也欢迎一般最佳实践建议 实际上 关于它的使用有相当明确的规则 可以追溯到HTML 2 0 http
  • 在不知道列名的情况下重命名单个 pandas DataFrame 列

    我知道我可以使用以下方法重命名单个 pandas DataFrame 列 drugInfo rename columns col 1 col 1 new name inplace True 但我想重命名一个列根据其索引 不知道它的名字 虽然
  • 如何更改TFS中的System.State字段?

    我有需要更改的要求System State现场workitem当其他字段发生变化时 我知道 TFS 工作流程是基于状态的 即根据状态您可以更改其他字段的值 但如何走另一条路呢 Mayur 我认为您无法通过使用内置工作项工作流程来实现这一目标
  • Mysql 获取刚刚插入的行

    所以我正在设计一个函数 将一行插入 MySQL 数据库 该表有一个启用了自动增量的主键 所以我不插入该列的值 但PK是整个表中唯一唯一的列 如何获取刚刚插入的行 如果该函数在流量较小的情况下我看不到问题 但是当其负载越来越重时 我可以看到一
  • 优化 SSE 代码

    我目前正在为 Java 应用程序开发一个 C 模块 需要一些性能改进 请参阅提高网络编码性能 https stackoverflow com questions 7737488 improving performance of networ
  • 如何从命令行获取 Ruby 文档 [重复]

    这个问题在这里已经有答案了 有没有办法找出我的哪一部分ri不显示 Ruby 文档的命令 ruby version ruby 1 9 3p392 2013 02 22 revision 39386 i686 linux ri version
  • 从 pandas 中具有多个值的列创建虚拟对象

    我正在寻找一种Python式的方法来处理以下问题 The pandas get dummies 方法非常适合从数据帧的分类列创建虚拟对象 例如 如果该列的值位于 A B get dummies 创建 2 个虚拟变量并相应地分配 0 或 1
  • 如何使用 Spring Jdbctemplate.update(String sql, obj...args) 获取插入的 id

    我正在使用 Jdbctemplate 我需要插入查询的 id 我读到我必须构建一个特定的PreparedStatement 并使用GenerateKeyHolder 对象 问题是在我的应用程序中所有插入方法都使用此 JdbcTemplate
  • 如何使用 AJAX 请求打开 jQuery UI 对话框?

    在我的网页上有一个 jQuery UI 对话框 当我单击按钮 创建新用户 时 它会打开一个新窗口 我的问题是如何使用 AJAX 请求打开该窗口 从另一个页面打开对话框表单会很好 例如 dialog html div title Create
  • Log4J 1.2 属性配置器 -> Log4J2

    目前 我们的应用程序使用 Log4J 1 2 并使用以下任一方式对其进行配置 File file PropertyConfigurator configure file getAbsolutePath or URL url Property
  • Mailgun:消息“已接受”,但需要很长时间才能送达(或未送达)

    我正在将 Mailgun 用于我维护的网站 通常 Mailgun 工作得很好 但我遇到了一个奇怪的问题 我的脚本调用 HTTP API 使用 Mailgun 发送消息 然后这些消息在我的日志中显示为 已接受 但随后需要很长时间才能 传送 通
  • 获取 HTML 元素中单击位置的文本

    我有一个包含一些文本的 div 元素 当用户单击该 div 内的单词时 我想突出显示该单词 为了做到这一点 我需要知道点击发生在文本中的哪个字符位置 这样我就可以找到附近的空白并在单词周围插入一些格式 找出文本中点击发生的位置是这里的技巧
  • 自动完成后端

    这是一个面试问题 设计一个自动完成的分布式后端 我会回答如下 自动完成是按给定后缀在字典中进行搜索 这本词典可能应该被组织为trie 该词典是根据最常见的查询构建的 但这是另一回事了 现在我假设字典不会经常更改 例如每天一次而不是每毫秒一次
  • 使用断言的最佳实践?

    使用是否存在性能或代码维护问题assert作为标准代码的一部分而不是仅将其用于调试目的 Is assert x gt 0 x is less than zero 比更好或更差 if x lt 0 raise Exception x is l
  • C++ 初始化数组指针

    如何初始化指向文字数组的指针 我希望 grid 指向新分配的 int 数组 1 2 3 int grid new int 3 grid 1 2 3 谢谢 你不能初始化这样就可以动态分配数组 你也不能assign以这种方式到数组 动态或静态
  • 在 OSX 上编译 clisp-2.49:未找到 LIBFFI

    TL DR Even if libffi似乎已安装 configure即使我给它添加 正确的 前缀 脚本也找不到它 这篇文章的最后一部分 是我陷入困境的地方 我仅提供其他信息来解释我如何到达那里 我对这篇长篇文章表示歉意 如果有些内容与您无
  • Git 克隆:“您似乎克隆了一个空存储库”

    我和一些同事一直致力于一个存储在私人 git 存储库中的项目 历史上没有问题 但最近我尝试克隆 遇到了以下问题 Cloning into project warning You appear to have cloned an empty
  • 限制从 Linq 列表中返回的结果数

    我正在使用 Linq EF4 1 从数据库中提取一些结果 并希望将结果限制为 X 个最新结果 其中X是用户设置的数字 有没有办法做到这一点 我目前正在将它们作为List如果这有助于限制结果集 虽然我可以通过循环来限制这一点 直到我点击 X
  • 默认 GNU 链接器脚本名称,以便 VIM 进行语法突出显示

    链接描述文件的常用后缀是什么 以便 VIM 对其使用语法突出显示 好像是 ld 仅据我所知 Vim 没有提供它的语法文件 至少我的没有 7 3 尝试提供下载的内容here http vim 1045645 n5 nabble com Syn
  • 优化内存密集型数据流管道的 GCP 成本

    我们希望降低在 GCP Dataflow 中运行特定 Apache Beam 管道 Python SDK 的成本 我们构建了一个内存密集型 Apache Beam 管道 每个执行器上运行需要大约 8 5 GB RAM 当前正在加载一个大型机