Hive 外部表處理技巧(二)


 

記錄日常工作中實際場景中,對hive分區表的一次啟發與實踐。
 

核心操作技巧

hive 指定分區locaiton,進行不同存儲位置或協議的數據讀取。
 

業務背景


在業務發展過程中,發現ucloud在某些峰值場景下會出現嚴重的數據問題,為了服務穩定性與存儲可靠性,需要做整體服務雲遷移的需求。

整體遷移技術背景:Ucloud -> Aliyun


當時設計遷移的方案:
計算集群與雲存儲服務並行,兩邊同時進行
Ucloud : 宿主機 + 自建 CDH + Ufile
Aliyun : EMR 服務 + Oss

雲存儲數據包括數據倉庫中各個層級數據,業務、日志數據全部都有,數據遷移耗時很長。

對於歷史底層數據的讀取,完全依賴於兩個雲存儲之間的數據遷移速度。
 

思考以及實踐測試

 
雖然在最初的方案下完成了整體數據遷移工作,但是自我進行思考復盤的時候,偶然看到hive外表的靈活操作,如果把這個特性應用於當時的數據遷移中,會過渡的平滑一些,而且只需要保留一個計算集群即可。

目前數據遷移已完成,目前測試是基於Aliyun EMR 環境測試,讀者如果有其他環境可以根據自己環境進行測試。
另外筆者不提供真實數據結果展示,只描述核心操作過程,因為整體測試表和數據是從真實數據和路徑修改而成,為了保護數據私密性,望大家見諒。
 
正文開始
 

准備工作


測試表 order:
CREATE EXTERNAL TABLE test_db.`order`(
`id` bigint , 
`pay_id` string , 
`order_id` bigint , 
`settle_id` bigint , 
`original_order_id` bigint , 
`order_type` string 
)
PARTITIONED BY ( 
`dt` string, 
`hour` string)
ROW FORMAT SERDE 
'org.openx.data.jsonserde.JsonSerDe' 
WITH SERDEPROPERTIES ( 
'ignore.malformed.json'='true') 
STORED AS INPUTFORMAT 
'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'

 

具體描述一下此表,此表為筆者實際測試表的部分數據,在建表時不指定location 的情況下,會默認指向hdfs存儲地址,如下:
 
DESCRIBE FORMATTED test_db.`order`;
 
會在尾部顯示location位置:
Location:               hdfs://emr-cluster/user/hive/warehouse/test_db.db/order    
Table Type:             EXTERNAL_TABLE      

 

至於數據格式,可以根據實際存儲數據格式進行SERDE設置,筆者使用json格式數據。
 

實踐過程

接下來可以設置不同分區指向不同地址。
ALTER TABLE test_db.`order` ADD IF NOT EXISTS PARTITION (dt = '2020-04-18', hour = '08')
LOCATION
'oss://datalake/order/dt=2020-04-18/hour=08'
;

ALTER TABLE test_db.`order` ADD IF NOT EXISTS PARTITION (dt = '2020-04-18', hour = '14')
LOCATION
'hdfs://emr-cluster/user/hive/warehouse/test_db.db/order/dt=2020-04-18/hour=14'
;

 

這樣接下來就可以分別查詢到存儲在oss和hdfs上的數據。
 
select * from test_db.`order` where dt = '2020-04-18' and hour = '08';

select * from test_db.`order` where dt = '2020-04-18' and hour = '14';

 

此測試完成Hdfs 與 Oss 底層數據,在同一張外表的情況下,完成不同分區訪問不同位置甚至不同雲存儲的數據。
預計 Hdfs 與其他雲存儲服務應該是相同的道理,只要hadoop配置了相應的雲存儲的配置,可以訪問的情況下可以跨協議讀取數據。

因為數據遷移已經完成,所以筆者在 Ufile 與 Oss之前的分別數據位置指定沒有測試過。

 

其他場景實踐測試

筆者使用此表,建表重新指向Oss的任意路徑,例如:
CREATE EXTERNAL TABLE test_db.`order`(
`id` bigint , 
`pay_id` string , 
`order_id` bigint , 
`settle_id` bigint , 
`original_order_id` bigint , 
`order_type` string 
)
PARTITIONED BY ( 
`dt` string, 
`hour` string)
ROW FORMAT SERDE 
'org.openx.data.jsonserde.JsonSerDe' 
WITH SERDEPROPERTIES ( 
'ignore.malformed.json'='true') 
STORED AS INPUTFORMAT 
'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'oss://datalake/test'

 

另外說明一下,oss://datalake/test 路徑下很多文件夾,但是沒有dt= ,hour= 開頭命名的文件夾。
 
 
將分區路徑設置為指定位置后,最后的查詢結果依然可以查詢出來。
ALTER TABLE test_db.`order` ADD IF NOT EXISTS PARTITION (dt = '2020-04-18', hour = '08')
LOCATION
'oss://datalake/order/dt=2020-04-18/hour=08'
;

select * from test_db.`order` where dt = '2020-04-18' and hour = '08';

 

從實踐結果來看,在跨越地址根目錄進行數據查詢的情況下,此方案仍然可行。

 


個人啟發

  • hive的分區靈活指定位置的可行性,在未來遇到數據遷移的場景下,提供了一條更加平滑、更加節省計算資源的遷移方案。
  • 例如 A集群 遷移到 B集群,理想情況下 ,可以只保留 B集群的計算集群,保留A、B集群的存儲即可。
  • 而在實際操作過程中,值得特別注意的是,需要實際調研實踐的是B計算集群訪問A集群存儲資源的可達性。
  • 或者可以更加寬泛的看待業務場景,存在數據跨協議、位置讀取的需求,此方案都可以作為一個備選項。

結束語

筆者在這里也只是拋磚引玉,也希望可以給大家一些啟發,在此基礎上,是否有更好的大數據遷移方案。
畢竟一個人的智慧是有限的,思維的碰撞也許得到不可思議的效果。
希望給大家實際工作中增加一些啟發,若有錯誤,煩請斧正。
 
 
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM