【问题标题】:spark Listing leaf files fails with File does not exist火花列出叶文件失败,文件不存在
【发布时间】:2020-05-15 03:12:57
【问题描述】:

在最近升级到 HDP 3.1 后,现在使用 spark 2.3.x 而不是 2.2.x,查询如下:

spark.sql("SELECT * from mydb.mytable").filter('partition_date between "202001010000" and "202001020000").write.parquet("foo.out")

从支持 HDFS 的配置单元表(无对象存储)读取时有时会失败。 您必须知道基础数据(Hive 中的 EXTERNAL 表)具有数据保留期,并且任何早于该日期的数据都将被删除。有时,在执行上述查询期间可能会发生这种删除。删除每 5 分钟发生一次。

即使:

PartitionFilters: [isnotnull(partition_date#3099), (partition_date#3099 >= 202001010000), (partition_date#3099 <= 202001020000)]

分区过滤(谓词下推)似乎比初始路径遍历期间读取的所需分区更多。 升级到 2.3 后,Spark 在 UI 中显示列出文件目录的进度。有趣的是,我们总是得到两个条目。一个用于最旧的可用目录,一个用于两个感兴趣边界中较低的一个:

Listing leaf files and directories for 380 paths:
/path/to/files/on/hdfs/mydb.db/mytable/partition_date==202001010000/sub_part=0, ...

Listing leaf files and directories for 7100 paths:
/path/to/files/on/hdfs/mydb.db/mytable/partition_date=201912301300/sub_part=0, ...

注意:

  • 记录的文件数(308、7100)似乎都不能反映手动检查的建议
  • 作业(有时)在叶文件的递归列表期间失败
  • 错误信息:

    文件不存在:/path/to/files/on/hdfs/mydb.db/mytable/partition_date=201912301300/sub_part=0/file_name_unique_hash_timestamp.par

如何强制 Spark 仅列出所需时间间隔内的目录而不列出外部目录,并可能与最长数据保留持续时间发生冲突?

看起来这是相关的:

【问题讨论】:

    标签: apache-spark apache-spark-sql hdfs directory-listing


    【解决方案1】:

    @meniluca 是正确的,因为它必须与 HDFS 可用的内容不匹配,并且 Hive 元存储报告为应该可用的内容。

    但是,与其使用看起来有点怪异/不易理解的视图(在读取操作中包含文件路径的情况下),我更喜欢:

    spark.read.option("basePath", "/path/to/mydb.db/mytable").orc("/path/to/mydb.db/mytable/partition_date=202001[1-2]*/*", "/path/to/mydb.db/mytable/partition_date=202001[3-4]*/*")
    

    这会强制 spark 列出正确的(所需路径)

    【讨论】:

      【解决方案2】:

      你试过this吗?

      spark.sql("MSCK REPAIR TABLE table_name")
      

      它救了我很多次。

      编辑。

      在 cmets 讨论后,请尝试创建一个视图。除非在删除分区后立即重新运行“select * from ...”,否则问题无法解决。

      创建视图将为您提供这样的解决方法:

      CREATE VIEW [IF NOT EXISTS] [db_name.]view_name [(column_name [COMMENT column_comment], ...) ]
        [COMMENT view_comment]
        [TBLPROPERTIES (property_name = property_value, ...)]
        AS SELECT * FROM mytable;
      

      来自Hive/LanguageManual+DDL

      然后用您的视图替换表格。如果您无权创建此类视图,请让管理员为您创建。他们应该满足这个要求,因为您似乎正在尝试解决他们的问题 IMO。

      【讨论】:

      • 它是一个外部表。更新后(每 5 分钟写入新文件)执行此命令以添加任何丢失的分区。所以你认为在列出目录之前运行它来清理分区有帮助吗?但是如果列出它们需要超过 5 分钟呢?然后它也可能崩溃。除此之外,作为分析用户,分析师可能没有写入表的权限,即执行此命令。
      • 确实,不是最终用户应该运行它。在您的作业删除分区后,您必须运行此命令或在 impala 中运行无效缓存。它也适用于外部分区。如果删除的文件数量比较少,那么它应该在几秒钟内运行。
      • 没有。这正是问题所在:删除分区不是我的工作,而是其他一些(3-rdparty)。他们还每 5 分钟添加一次新数据,然后调用此命令以使分区可用,所以我认为这不会有帮助。
      • 不,这无济于事。安全阅读它的唯一方法是使用视图。我正在更新我的答案。
      • 有趣,为什么视图会解决这个问题?我还不明白这一点。你能进一步解释一下吗?
      猜你喜欢
      • 2019-08-16
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      相关资源
      最近更新 更多