你如何控制输出文件的大小?

use*_*359 9 apache-spark parquet

在spark中,控制输出文件大小的最佳方法是什么.例如,在log4j中,我们可以指定最大文件大小,然后文件旋转.

我正在寻找类似的镶木地板文件的解决方案.编写文件时是否有可用的最大文件大小选项?

我的解决方法很少,但没有一个是好的.如果我想将文件限制为64mb,那么一个选项是重新分区数据并写入临时位置.然后使用临时位置中的文件大小将文件合并在一起.但是获取正确的文件大小很困难.

sou*_*ine 30

Spark无法控制Parquet文件的大小,因为内存中的DataFrame需要在写入磁盘之前进行编码和压缩.在此过程完成之前,无法估计磁盘上的实际文件大小.

所以我的解决方案是:

  • 将DataFrame写入HDFS, df.write.parquet(path)
  • 获取目录大小并计算文件数

    val fs = FileSystem.get(sc.hadoopConfiguration)
    val dirSize = fs.getContentSummary(path).getLength
    val fileNum = dirSize/(512 * 1024 * 1024)  // let's say 512 MB per file
    
    Run Code Online (Sandbox Code Playgroud)
  • 读取目录并重新写入HDFS

    val df = sqlContext.read.parquet(path)
    df.coalesce(fileNum).write.parquet(another_path)
    
    Run Code Online (Sandbox Code Playgroud)

    不要重复使用原件df,否则会触发你的工作两次.

  • 删除旧目录并重新命名新目录

    fs.delete(new Path(path), true)
    fs.rename(new Path(newPath), new Path(path))
    
    Run Code Online (Sandbox Code Playgroud)

该解决方案的缺点是需要将数据写入两次,这会使磁盘IO加倍,但目前这是唯一的解决方案.

  • @soulmachine - 你能详细说明一下“不要重复使用原始的 df,否则它会触发你的工作两次。” (4认同)

sel*_*lle 8

Spark 中还没有特定大小后滚动的选项,但最好是在特定数量的记录之后滚动。

Spark 2.2开始,可以设置maxRecordsPerFile.

另请参阅/sf/answers/3370032081/

  • 你知道是否有像 minRecordsPerFile 这样的东西吗? (2认同)