使用相同的源和相同的邏輯創建了 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 查詢 - 相同的邏輯,使用外部爆炸縮短:
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 讀取程序嗎?
PS Hive 版本是 2.3.3,Spark 版本是 2.4.4
uj5u.com熱心網友回復:
通常資料檔案位于沒有子目錄的表位置內。
UNION ALL 正在優化(很可能您正在使用 Tez),并且每個查詢都并行運行,作為單獨的映射器任務獨立運行。這需要為 UNION ALL 中的每個查詢創建單獨的子目錄,以便可以同時寫入每個查詢的結果,這就是您有兩個目錄的原因。
這些設定允許 Hive 讀取子目錄:
set hive.input.dir.recursive=true;
set hive.mapred.supports.subdirectories=true;
有一個問題SPARK-26663 - 無法查詢帶有子目錄的 Hive 表- 由于無法重現而關閉,因為他們執行了在 MR 而不是 Tez 上重現的步驟。
如果您需要閱讀此類表,請嘗試使用 HiveContext 并設定上述屬性。
順便說一句,您的第二個查詢更有效,因為您只讀取一次源表并且不創建子目錄。
您也可以嘗試在 MR 上運行 CREATE TABLE,它不會創建子目錄 ( set hive.execution.engine=mr;)。
還將 UNION ALL 包裝到子查詢中并添加諸如 DISTRIBUTE BY 或 ORDER 之類的內容將強制執行額外的減少步驟,請參閱https://stackoverflow.com/a/54998031/2700344
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/364889.html
