将大文件写入S3的最佳方法是什么?

时间:2020-05-15 20:05:38

标签: apache-spark pyspark parquet apache-zeppelin

我正在使用齐柏林飞艇和Spark,我想从S3中提取2TB文件,并在Spark中对其进行转换,然后将其发送到S3,以便我可以在Jupyter笔记本中使用该文件。转换非常简单。

我正在将文件读取为实木复合地板文件。我认为大约是2TB,但是我不确定如何验证。

大约有1000万行和5列,所以它很大。

我尝试做my_table.write.parquet(s3path),而我尝试了my_table.write.option("maxRecordsPerFile", 200000).parquet(s3path)。如何提出正确的方法来编写大型木地板文件?

2 个答案:

答案 0 :(得分:2)

这些是您可以考虑的要点...

1)maxRecordsPerFile设置:

使用

my_table.write.parquet(s3path)

Spark为每个任务写出一个文件。

保存的文件数=正在保存的RDD / Dataframe的分区数。因此,这可能会导致文件大得离谱(因为您可以对数据进行分区并保存分区意味着在网络上重新整理数据。)。

限制每个文件的记录数

my_table.write.option("maxRecordsPerFile", numberOfRecordsPerFile..yourwish).parquet(s3path)

它可以避免生成大文件。

2)如果您使用的是AWS Emr(Emrfs),则可能是您可以考虑的重点之一。

emr-spark-s3-optimized-committer

未使用EMRFS S3优化的提交器时:

  • 使用S3A文件系统时。
  • 使用Parquet以外的输出格式时,例如ORC或文本。

3)使用压缩技术,算法版本和其他Spark配置:

.config("spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version", 2)
.config("spark.hadoop.mapreduce.fileoutputcommitter.cleanup-failures.ignored", true)
.config("spark.hadoop.parquet.enable.summary-metadata", false)
.config("spark.sql.parquet.mergeSchema", false)
.config("spark.sql.parquet.filterPushdown", true) // for reading purpose 
.config("mapreduce.fileoutputcommitter.algorithm.version", "2")
.config("spark.sql.parquet.compression.codec", "snappy")
.getOrCreate()

4)如果您使用的是s3a,则可以进行快速上传和其他道具:

  .config("spark.hadoop.fs.s3a.fast.upload","true")
  .config("spark.hadoop.fs.s3a.fast.upload","true")
  .config("spark.hadoop.fs.s3a.connection.timeout","100000")
  .config("spark.hadoop.fs.s3a.attempts.maximum","10")
  .config("spark.hadoop.fs.s3a.fast.upload","true")
  .config("spark.hadoop.fs.s3a.fast.upload.buffer","bytebuffer")
  .config("spark.hadoop.fs.s3a.fast.upload.active.blocks","4")
  .config("fs.s3a.connection.ssl.enabled", "true")

答案 1 :(得分:0)

  1. S3a连接器将递增地写入块,但是hadoop-2.7.x中带有spark的(过时)版本不能很好地处理它。如果可以的话,将所有hadoop- Jars更新为2.8.5或2.9.x。
  2. 选项"fs.s3a.multipart.size控制块的大小。限制为1万个块,因此您可以上传的最大文件为该大小* 10,000。对于非常大的文件,请使用比默认值“ 64M”更大的数字