我注意到,对于这样一个简单的工作(读取orc数据,以Parquet格式写出它们):
val df = spark.read.option("basePath", "/projects/mydb/mytable").format("org.apache.spark.sql.execution.datasources.orc").load("/projects/mydb/mytable/*")
val df2 = df.select("field1","field2","field3")
df2.write.option("mapreduce.fileoutputcommitter.algorithm.version", "2").format("parquet").save("/projects/outputfolder1/")
与hive(只是一个简单的insert表select from…)相比,spark需要很长的时间(和更多的资源)。
实际计划看起来没什么特别的,比如:
Execute InsertIntoHadoopFsRelationCommand InsertIntoHadoopFsRelationCommand xxxx(source folder), false, format, Map(mapreduce.fileoutputcommitter.algorithm.version -> 2, path -> xyz_path), Overwrite, [field1, field2, field3]
+- *(1) Project [field1, field2, field3]
+- *(1) FileScan orc ...
在观察它如何使用不同的参数(驱动程序/执行程序内存、内核、spark.sql.files.maxpartitionbyte等)工作和播放时,看起来spark会先将数据读入内存,然后再将其写出来有没有办法告诉spark在读的时候把它写出来(在这种情况下,不需要先将所有数据保存在内存中)。
谢谢。
我使用的是spark 2.4.4,hive 1.2.1。谢谢
1条答案
按热度按时间mrphzbgm1#
考虑到文件到文件的拷贝总是使用ram,也就是说,i/o操作(几乎总是)在外设和ram之间:1)文件-->ram,2)ram-->文件,这意味着spark也必须使用ram来执行此类操作。
所以,简单的答案是否定的。
另请参见此链接,顺便说一句:https://superuser.com/questions/988363/why-do-file-transfers-between-drives-use-ram
简而言之,这是一个一般原则。