将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上创建数千个小文件,这需要很长时间,而在我不喜欢的时候就没有必要更少的大文件。
答案 0 :(得分:1)
这是因为您使用limit
。至于现在(有an ongoing discussion on the developers list所以它将来可能会改变)limit
将所有数据重新分配到单个分区。由于coalesce
只能减少分区数量,因此无效。
出于性能原因,sample
和coalesce
应该更好。例如:
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
。