Spark:加载过程中的分组

时间:2016-08-21 15:40:47

标签: scala apache-spark

通常我加载csv文件,然后运行不同类型的聚合,例如使用Spark“group by”。我想知道是否有可能在文件加载期间启动这种操作(通常是几百万行)而不是顺序化它们,如果它值得(节省时间)。

示例:

JAVA_OPTS

为了解Spark是如何工作的,val csv = sc.textFile("file.csv") val data = csv.map(line => line.split(",").map(elem => elem.trim)) val header = data.take(1) val rows = data.filter(line => header(0) != "id") val trows = rows.map(row => (row(0), row)) trows.groupBy(//row(0) etc.) (或groupBy)将被“推迟”到整个文件csv的内存加载中。如果这是正确的,加载和分组是否可以在“相同”时间运行而不是对两个步骤进行排序?

2 个答案:

答案 0 :(得分:3)

  

groupBy(或聚合)将被“推迟”到整个文件csv的内存加载中。

事实并非如此。在本地(单个分区)级别,Spark对延迟序列进行操作,因此属于单个任务的操作(包括地图侧聚合)可以压缩在一起。

换句话说,当你有方法链时,操作是逐行执行而不是按转换转换。换句话说,第一行将被映射,过滤,再次映射并在访问下一行之前传递给聚合器。

答案 1 :(得分:1)

通过加载操作启动组您可以继续使用2个选项:

  1. 编写自己的加载程序,并在+ aggregationByKey中创建您自己的组。其缺点是编写了更多代码和代码。更多维护。
  2. 使用 Parquet格式文件作为输入+ DataFrames ,由于它是柱状的,它只会读取groupBy中使用的所需列。所以它应该更快。 - DataFrameReader

    df = spark.read.parquet('file_path')
    df = df.groupBy('column_a', 'column_b', '...').count()
    df.show()
    
  3. Due Spark是懒惰的,在你调用show / collect / write之类的动作方法之前,它不会加载你的文件。因此,Spark将知道哪些列读取以及哪些列在加载过程中忽略。