Apache spark 在Pyspark(Spark 2.1.1)中,将数据帧写入磁盘花费了不现实的长时间

Apache spark 在Pyspark(Spark 2.1.1)中,将数据帧写入磁盘花费了不现实的长时间,apache-spark,pyspark,spark-dataframe,Apache Spark,Pyspark,Spark Dataframe,我在一台带有多个CPU的服务器上运行Pyspark。除写入磁盘外,所有其他操作(读取、加入、筛选、自定义自定义自定义项)都可以快速执行。我试图保存的数据帧大小约为400GB,有200个分区 sc.getConf().getAll() 驱动程序内存为16g,工作目录有足够的空间(>10TB) 我正在尝试使用以下命令保存: df.repartition(1).write.csv("out.csv") 想知道是否有人遇到过同样的问题。另外,在调用pyspark之前更改任何配置参数是否有助于解决

我在一台带有多个CPU的服务器上运行Pyspark。除写入磁盘外,所有其他操作(读取、加入、筛选、自定义自定义自定义项)都可以快速执行。我试图保存的数据帧大小约为400GB,有200个分区

 sc.getConf().getAll()
驱动程序内存为16g,工作目录有足够的空间(>10TB)

我正在尝试使用以下命令保存:

 df.repartition(1).write.csv("out.csv")
想知道是否有人遇到过同样的问题。另外,在调用pyspark之前更改任何配置参数是否有助于解决此问题

编辑(一些澄清):

当我的意思是其他操作被快速执行时,在转换之后总是有一个操作,在我的例子中,它们是行计数。所以所有的操作都执行得非常快。我还没弄明白为什么写作要花这么多时间

我的一位同事提出了一个事实,即我们服务器中的磁盘可能对并发写入有限制,这可能会减慢速度,目前仍在对此进行调查。有兴趣知道其他人是否也看到Spark群集上的写入时间很慢。我从一个用户那里得到了关于AWS集群的确认

所有其他操作(读取、加入、筛选、自定义自定义自定义项)

这是因为存在转换—在必须保存数据之前,它们不会执行任何操作

我试图保存的数据帧大小约为400GB (...) 我正在尝试使用以下命令保存:

df.repartition(1).write.csv("out.csv")
这是行不通的。即使忽略使用一台机器的部分,用一个线程(!)节省400GB也是毫无希望的。即使它成功了,也不比使用普通bash脚本好


跳过400GB的Spark顺序写入将花费大量时间,即使是在平均大小的磁盘上。在多次洗牌(
join
repartition
)的情况下,数据将被多次写入磁盘。

经过多次尝试和错误后,我意识到问题是由于我从磁盘读取文件的方法造成的。我正在使用内置的read.csv函数,当我切换到databricks csv包中的read函数时,问题就消失了。我现在能够在合理的时间将文件写入磁盘。这真的很奇怪,可能是2.1.1中的一个bug,或者databricks csv包真的优化了

1.read.csv方法

from pyspark.sql import SparkSession
spark = SparkSession \
    .builder \
    .appName("model") \
    .config("spark.worker.dir", "xxxx") \
    .getOrCreate()
df = spark.read.load("file.csv", format="csv", header = True)
write.csv("file_after_processing.csv")
2.使用DataRicks csv包

from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)


df = sqlContext.read.format('com.databricks.spark.csv').options(header='true', inferschema='true').load('file.csv')
train.write.format('com.databricks.spark.csv').save('file_after_processing.csv')

当我的意思是执行时,在转换后有一个动作,在我的例子中,它们是行计数。所以所有的操作都执行得非常快。我确实更改了分区的数量,也在没有重新分区选项的情况下运行了该命令,但仍然需要很多时间。