通常我加载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的内存加载中。如果这是正确的,加载和分组是否可以在“相同”时间运行而不是对两个步骤进行排序?
答案 0 :(得分:3)
groupBy(或聚合)将被“推迟”到整个文件csv的内存加载中。
事实并非如此。在本地(单个分区)级别,Spark对延迟序列进行操作,因此属于单个任务的操作(包括地图侧聚合)可以压缩在一起。
换句话说,当你有方法链时,操作是逐行执行而不是按转换转换。换句话说,第一行将被映射,过滤,再次映射并在访问下一行之前传递给聚合器。
答案 1 :(得分:1)
通过加载操作启动组您可以继续使用2个选项:
使用 Parquet格式文件作为输入+ DataFrames ,由于它是柱状的,它只会读取groupBy中使用的所需列。所以它应该更快。 - DataFrameReader
df = spark.read.parquet('file_path')
df = df.groupBy('column_a', 'column_b', '...').count()
df.show()
Due Spark是懒惰的,在你调用show / collect / write之类的动作方法之前,它不会加载你的文件。因此,Spark将知道哪些列读取以及哪些列在加载过程中忽略。