Spark'saveAsTextFile'到S3:无法用'coalesce'控制文件数

时间:2017-01-20 20:18:25

标签: python apache-spark amazon-s3 pyspark apache-spark-sql

将Python 3与PySpark和Spark 1.6.0结合使用。我已经读过saveAsTextFile()创建的文件数等于RDD分区数。但是,我特意将RDD合并到16个分区,但只有1个文件被写入S3(part-00000.gz)。我做错了什么?

这是我正在使用的代码:

conf = SparkConf()
sc = SparkContext(conf=conf)
sc.setLogLevel('WARN')
sc._jsc.hadoopConfiguration().set('fs.s3a.access.key', AWS_ACCESS_KEY)
sc._jsc.hadoopConfiguration().set('fs.s3a.secret.key', AWS_SECRET_KEY)
sqlContext = HiveContext(sc)

tbl = sqlContext.table(TABLE)
tbl.limit(1000000).toJSON().coalesce(16).saveAsTextFile(S3A_BUCKET_URL, compressionCodecClass="org.apache.hadoop.io.compress.GzipCodec")

原始TABLE是Parquet存储在大约11,000个文件中(我假设它等于Spark分区?)。当我不在整个表上使用limit()coalesce()时,它会尝试在S3上创建数千个小文件,这需要很长时间,而在我不喜欢的时候就没有必要更少的大文件。

1 个答案:

答案 0 :(得分:1)

这是因为您使用limit。至于现在(有an ongoing discussion on the developers list所以它将来可能会改变)limit将所有数据重新分配到单个分区。由于coalesce只能减少分区数量,因此无效。

出于性能原因,samplecoalesce应该更好。例如:

from operator import truediv

df.cache()
n = ... # Number of records to take
m = df.count()

df.sample(withReplacement=False, fraction=truediv(n / m))

但如果您想使用确切的limit,则必须repartition而不是coalesce