我的数据集大小都在 1GB 以下,而我的转换的总输出大小在 1GB 以下。我注意到我的工作簿构建对于我期望的数据规模来说非常慢,我想知道我可以转向哪些“拨号”来优化这些。
例如,我在构建的 Spark 详细信息中看到,我的几个阶段有 200 个任务,每个任务只获取几 KB 的数据。那正确吗?
我的数据集大小都在 1GB 以下,而我的转换的总输出大小在 1GB 以下。我注意到我的工作簿构建对于我期望的数据规模来说非常慢,我想知道我可以转向哪些“拨号”来优化这些。
例如,我在构建的 Spark 详细信息中看到,我的几个阶段有 200 个任务,每个任务只获取几 KB 的数据。那正确吗?
在这种数据规模下,您可以对构建产生一些影响,以使其更适当地优化。
值得验证您的构建正在使用AQE运行,如此处所述。这将确保您的阶段不会将其工作分成 200 个任务(对于这种规模来说太多了,KB 范围内的任务将受到太多网络 I/O 的影响)。
任务的默认大小可能适合您的工作,因此除非另有证明,否则不要修改建议分区大小。
由于您的数据规模足够小,您可以考虑使用所谓的 Spark“本地模式”。这是您不使用任何 Executor 来完成您的工作,而是将您的工作的全部内容保存在 Driver 本身中的时候。这意味着您不会跨集群移动数据以执行join
s、window
s、groupBy
s 等,而是将其全部保存在 Driver 主机上的内存中。这只适用于所有数据确实可以放入内存的情况,但对于确实如此的小规模,这意味着您的数据的访问和使用速度要快得多。
在代码存储库中,您将应用KUBERNETES_NO_EXECUTORS
到您的转换,在代码工作簿中,您需要联系您的 Palantir 支持工程师来配置此行为。
然后您将看到您的转换分配了零个执行程序,但仍有一些任务并行运行。它们都将使用驱动程序拥有的每个内核在您的驱动程序上并行运行。 注意:请非常小心,不要将内核数量增加得太高,否则您将增加此处的指导导致 OOM 的风险。从本质上讲,随着核心数量的增加,每个核心的内存份额实际上会减少,这将增加单个任务 OOMing 的风险。您也不想为驱动程序订阅太多内核以获得更好的“并行性”,因为如果您的并行任务远远超过 4 个,您可能应该考虑使用标准的基于 Executor 的计算设置。
由于您现在仅使用驱动程序上的资源,因此您可能需要增加内核数量以支持正在运行的最大任务数。在典型的设置中,这是 4,因此您将DRIVER_CORES_LARGE
在代码存储库中申请,并且同样会联系您的 Palantir 支持以在代码工作簿中进行配置。
作为补充说明,值得强调的是,Spark 本身使用Catalyst 引擎进行查询规划过程,从而为您的工作进行优化,以便在构建输出时尽可能减少工作量。这些优化需要时间来执行,这意味着您可能会发现计划查询所花费的时间超过了查询的实际执行时间。在超过约 1GB 输入大小的范围内,这是一个特征;在此示例的规模中,这意味着您的性能比更简单的系统稍差。但是,如果您的数据规模增加,此优化步骤对于保持可扩展性和性能至关重要。