如何避免在查询Spark正在加载的配置单元表时出错



我们有一个用例,在一些流数据之上运行用spark编写的ETL,ETL每小时将结果写入目标配置单元表,但用户通常会对目标表运行查询,我们也遇到过由于spark同时加载表而导致查询错误的情况。我们有什么替代方案来避免或最大限度地减少这种错误?火花作业(或配置单元表(有任何属性吗?或者创建一个临时表之类的东西?

错误为:

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

我认为发生这种情况是因为元数据显示有一个文件a在作业执行过程中被删除。

该表按年、月、日进行分区(使用HDFS作为存储(,每次ETL运行时,它只更新(通过分区覆盖(当前日期分区。目前没有";事务性的";集群中启用了表(即使我在测试集群上测试了用例,也没有运气(

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

有一组两个表和它们的视图:

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迭代

不确定,但请查看

创建表foo_a(…(;CREATE TABLE foo_b(…(;

最新更新