以镶木地板格式保存数据框会生成太多小文件

时间:2018-03-15 08:20:44

标签: sql pyspark spark-dataframe parquet

使用Spark Sql我在hive表中以镶木地板格式保存spark df。 问题是此操作始终生成大约200个3 MB文件。如何在处理过程中控制输出文件的数量和分区数?据我所知,每个分区都会生成一个part- *文件。

我的工作流程如何:

  1. 我使用spark.read.parquet("")
  2. 从Hive Metastore中的表中读取了一个分区
  3. 然后我从这个df
  4. 创建一个TempView
  5. 然后我用纯sql做我需要的转换,它有很多连接:spark.sql("SQL QUERY")
  6. 然后我尝试对结果进行重新分区合并,这不起作用,因为part- *文件的数量总是200
  7. 我用spark.sql(" insert overwrite partition() ... ")
  8. 保存了我的df

    我使用纯sql的原因是因为如果尝试使用Dataframe API保存我的df,我会失去列的排序。

    我在CDH 11.2中使用Spark 2.2.0

    如果我的问题中有一些非慈善机构,请告诉我。

    UPDATE1: 示例源代码

    conf = (SparkConf()
    .set("spark.serializer","org.apache.spark.serializer.KryoSerializer")
    .set("spark.sql.parquet.compression.codec","SNAPPY")
    .set("spark.executor.cores", "3")
    .set("spark.executor.instances", "10")
    .set("spark.executor.memory", "20g")
    )
    
    sc = SparkContext(conf=conf)
    
    spark = SparkSession \
        .builder \
        .config(conf=conf) \
        .getOrCreate()
    
    df=spark.read.parquet("/user/hive/warehouse/schema.db/tbl/year=2000/month=01/day=01").cache()
    
    temp_table_name="tmp_bal2_nor_20000101"
    df.createOrReplaceTempView(temp_table_name)
    
    aaa=spark.sql(
    """ select DISTINCT t.A,
                        t.lot,
                        t.of,
                        t.columns,
                        .
                        .,
        from temp_table_name t 
    left join( 
        ...
    ) tmp1 on ...
    left join( 
        ...
    ) tmp2 on ...
    left join( 
        ...
    ) tmp3 ...
    left join( 
        ...
    ) tmp4 on ...
    left join( 
        ...
    ) tmp5 on ...
    left join( 
        ...
    ) tmp6 on ...
    order by t.A, t.lot """
    )
    
    aaa.coalesce(10).createOrReplaceTempView(temp_table_name)
    spark.sql(""" insert overwrite table tbl1
    PARTITION(year=2000, month=01, day=01)
    select DISTINCT t.A, 
                     t.lot, 
                     t.of, 
                     t.columns
    from temp_table_name t
    """)
    
    spark.stop()
    

1 个答案:

答案 0 :(得分:1)

尝试更改代码以便在使用合并后保存镶木地板文件。如下:

 aaa.coalesce(10).write.parquet("your_path")

否则通常会忽略coalesce,因为在减少分区后,您将使用 aaa 数据集创建TempView。目前您有200个分区,因为 spark.sql.shuffle.partitions 设置为200,这是Spark SQL的默认分区号。 coalesce只是数据集的一部分,因此如果要正确使用它,则需要直接通过数据集进行。