【问题标题】:how to avoid errors when querying hive table being loaded by Spark at the same time查询Spark同时加载的hive表时如何避免错误
【发布时间】:2020-09-17 20:25:39
【问题描述】:

我们有一个用例,我们在一些流数据之上运行用 Spark 编写的 ETL,ETL 每小时将结果写入目标 hive 表,但用户通常对目标表运行查询,我们遇到过案例由于火花同时加载表而出现查询错误。我们有哪些替代方法可以避免或尽量减少这种错误?火花作业(或蜂巢表)的任何属性?还是创建一个临时表之类的?

错误是:

java.io.FileNotFoundException: 文件不存在 [HDFS PATH]

我认为这是因为元数据显示有一个文件 A 在作业执行期间被删除。

该表按年、月、日分区(使用 HDFS 作为存储),每次 ETL 运行时都会更新(通过分区覆盖)当前日期分区。目前集群中没有启用“事务”表(即使我在没有运气的情况下在测试集群上测试了用例)

【问题讨论】:

  • 您的数据究竟存储在哪里? S3? HDFS?还有什么是完整的堆栈跟踪?您是直接操作文件还是使用 Table 抽象?
  • 数据存储在HDFS中,使用表抽象(将spark数据帧写入hive),更详细的错误:异常:错误:状态:失败错误:顶点失败,顶点名称=地图1,顶点ID=顶点_1585784648138_16268_15_00,诊断= [任务失败,taskId = task_1585784648138_16268_15_00_000022,诊断= [TaskAttempt 0失败,信息= [错误:运行任务时失败:java.lang.RuntimeException:java.lang.RuntimeException:java.io.IOException:java.io.FileNotFoundException :文件不存在:

标签: apache-spark hive


【解决方案1】:

简单的选择是使用一种表格式,该表格式旨在处理并发读取和写入,如 hudi 或 delta Lake。更复杂的版本涉及使用写入者写入的分区追加表。完成后,作者更新视图以指向新数据。另一种可能的选择是在插入时对表进行分区。

【讨论】:

    【解决方案2】:

    有一组两个表和一个视图:

    CREATE TABLE foo_a (...);
    CREATE TABLE foo_b (...);
    CREATE VIEW foo AS SELECT x, y, z, ... FROM foo_a;
    

    ETL 流程的第一次迭代需要:

    1. 同步foo_a -> foo_b
    2. foo_b 上工作
    3. 删除视图foo 并重新创建它指向foo_b

    在第 3 步之前,用户查询针对表 foo_a 运行。从切换的那一刻起,他们就与foo_b 对抗。 ETL 的下一次迭代将以相反的方式工作。

    这并不完美。在 ETL 中,您需要双重存储和一些额外的复杂性。无论如何,如果出现以下情况,这种方法可能会失败:

    • 用户很不幸,在下降和下降之间的时间很短 重新创建视图
    • 用户提交的查询量足以在两次 ETL 迭代中运行

    【讨论】:

      【解决方案3】:

      不确定,但检查一下

      创建表 foo_a (...); 创建表 foo_b (...);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-31
        • 1970-01-01
        • 2019-08-18
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 2017-07-16
        相关资源
        最近更新 更多