【发布时间】:2022-01-02 23:02:45
【问题描述】:
使用相同的源和相同的逻辑创建了 2 个 Hive 表,但查询略有不同:
表1查询是:
create table test.table1 stored as orc as
select
f1,
mc.f2 as f2,
mc.f3 as f3,
f4
from src.test_table lateral view explode(multiple_field) mcTable as mc
union all
select
f1,
f5 as f2,
f6 as f3,
f4
from src.test_table
where multiple_field is null or size(multiple_field) < 1
;
接下来,表 2 查询 - 相同的逻辑,使用 outerexplode 缩短:
create table test.table2 stored as orc as
select
f1,
if(mc is null, f5, mc.f2) as f2,
if(mc is null, f6, mc.f3) as f3,
f4
from src.test_table lateral view outer explode(multiple_field) mcTable as mc
;
两个表均已成功创建,包含相同的行数和相同的数据(由 Hive Beeline 客户端检查)。 然后我尝试用 Spark 读取表的数据:
SparkSession sparkSession = SparkSession
.builder().config("hive.execution.engine","mr")
.appName("OrcExportJob")
.enableHiveSupport()
.getOrCreate();
String hql = "select * from test.table1"; // or test.table2
Dataset<Row> sqlDF = sparkSession.sql(hql);
在 test.table2 的情况下没关系 - sqlDF 包含所有数据。 读取 test.table1 会导致不同的结果 - sqlDF 根本不包含任何数据(0 行)。 Spark 日志显示没有错误 - 就像表真的是空的一样。
我听说 Spark 在读取事务性或分区 Hive 表时遇到了一些问题 - 但事实并非如此。
四处挖掘,我发现 Hive 以不同的方式为我的表存储 ORC 文件:
/
├─ user/
│ ├─ hive/
│ │ ├─ warehouse/
│ │ │ ├─ test.db/
│ │ │ │ ├─ table1/
│ │ │ │ │ ├─ 1/
│ │ │ │ │ │ ├─ 1/
│ │ │ │ │ │ │ ├─ 000000_0
│ │ │ │ │ ├─ 2/
│ │ │ │ │ │ ├─ 000000_0
│ │ │ │ │ │ ├─ 000001_0
│ │ │ │ │ │ ├─ 000002_0
│ │ │ │ │ │ ├─ 000003_0
│ │ │ │ ├─ table2/
│ │ │ │ │ ├─ 000000_0
│ │ │ │ │ ├─ 000001_0
│ │ │ │ │ ├─ 000002_0
│ │ │ │ │ ├─ 000003_0
有人可以帮我找出 Spark 看不到表 1 数据的原因吗?
为什么 Hive 为表 1 保留 5 个目录结构复杂的文件,而表 2 只保留 4 个结构简单的文件?
它会以某种方式影响 Spark 读取过程吗?
附: Hive 版本是 2.3.3, Spark 版本是 2.4.4
【问题讨论】:
标签: apache-spark hadoop hive