首页 > 解决方案 > 尽管我增加了节点数,但 Spark csv 读取速度很慢

问题描述

我在 Google Compute Engine 上创建了两个集群,这些集群读取 100 GB 数据。

集群 I:1 个主节点 - 15 GB 内存 - 250 GB 磁盘 10 个节点 - 7.5 GB 内存 - 200 GB 磁盘

集群 II:1 个主节点 - 15 GB 内存 - 250 GB 磁盘 150 个节点 - 1.7 GB 内存 - 200 GB 磁盘

我正在使用它来读取文件:

val df = spark.read.format("csv")
    .option("inferSchema", true)
    .option("maxColumns",900000)
    .load("hdfs://master:9000/tmp/test.csv")

这也是一个包含 55k 行和 850k 列的数据集。

Q1:虽然我增加了机器数量,但我没有看到阅读速度有明显的提高。有什么问题或该怎么做才能使此过程更快?我应该更多地增加节点吗?

Q2:机器数量的增加对更快更重要还是内存量的增加对 Spark 很重要?节点、内存和速度之间是否有性能图?

Q3:hadoop 的复制或移动命令也很慢。数据只有 100 GB。大公司如何处理 TB 级数据?我无法捕捉到数据读取速度的提高。

感谢您的回答

标签: scalacsvapache-sparkhadoopgoogle-compute-engine

解决方案


TL;DR Spark SQL(以及一般的 Spark 和其他共享相似架构和设计的项目)主要设计用于处理长且(相对)窄的数据。这与您的数据完全相反,其中输入很宽且(相对)短。

请记住,尽管 Spark 使用列格式进行缓存,但其核心处理模型处理数据的行(记录)。如果数据宽而短,它不仅限制了数据分布的能力,而且更重要的是,会导致非常大的对象的初始化。这对整体内存管理和垃圾收集过程(什么是 JVM GC 的大对象)产生不利影响。

在 Spark SQL 中使用非常广泛的数据会导致其他问题。就查询中使用的表达式而言,不同的优化器组件具有非线性复杂性。这通常不是数据狭窄(< 1K 列)的问题,但很容易成为更广泛数据集的瓶颈。

此外,您使用的输入格式不太适合高性能分析和昂贵的阅读器选项(模式推理)。

根据您对数据的了解以及以后计划如何处理数据,您可以尝试解决其中的一些问题,例如在读取时转换为长格式,或直接使用一些稀疏表示(如果适用)对数据进行编码。

除此之外,您最好的选择是根据运行时统计数据仔细调整内存和 GC。


推荐阅读