【问题标题】:Repartition to avoid large number of small files重新分区以避免大量小文件
【发布时间】:2018-10-20 20:49:42
【问题描述】:

目前我有一个 ETL 作业,它读取几个表,执行某些转换并将它们写回日常表。

我在 spark sql 中使用以下查询 "INSERT INTO dbname.tablename PARTITION(year_month) 从 Spark_temp_table 中选择 *" 插入所有这些记录的目标表按年 X 月级别进行分区。每天生成的记录并不多,因此我在 X 年级别进行分区。

但是,当我检查分区时,我的代码运行的每一天都有大约 50MB 的小文件(代码必须每天运行),最终我的分区中将有大约 30 个文件,总计大约 1500MB

我想知道我是否有办法只在一个分区中创建一个(或根据块大小限制创建 2-3 个文件),而我每天都附加我的记录

我认为我可以做到的方法是从我的 spark 数据框中的相关分区中读取所有内容,将其附加最新记录并在回写之前对其进行重新分区。如何确保我只从相关分区读取数据,并且只有该分区被较少数量的文件覆盖?

【问题讨论】:

    标签: apache-spark hadoop apache-spark-sql pyspark-sql


    【解决方案1】:

    您可以使用DISTRIBUTE BY 子句来控制记录在每个分区内的文件中的分布方式。

    每个分区只有一个文件,你可以使用DISTRIBUTE BY year, month

    每个分区有 3 个文件,你可以使用DISTRIBUTE BY year, month, day % 3

    完整的查询:

    INSERT INTO dbname.tablename 
    PARTITION(year_month) 
    SELECT * from Spark_temp_table
    DISTRIBUTE BY year, month, day % 3
    

    【讨论】:

    • 感谢 lev 的回答。我还浏览了许多讨论相同问题的博客,我了解到每个分区可能会出现大量文件,原因有两个:1:当大量 reducer(默认为 ~200)正在向您的数据库写入数据时分区和2:当您每天插入分区时(假设您的分区是每月一次)。我相信你提到的可以解决问题1,但我应该如何避免问题2?
    • 另外,你刚才说的也可以用这些命令修复吧? (他们将再次解决分区中的大文件小于分配的块大小的问题)set hive.merge.mapredfiles=trueset hive.merge.size.per.task =256000000设置 hive.merge.smallfiles.avgsize=256000000
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 2012-10-23
    • 2023-03-13
    • 2022-12-17
    • 2012-07-02
    • 1970-01-01
    相关资源
    最近更新 更多