背景
這一篇可以說是“Hive JSON數據處理的一點探索”的兄弟篇。
平台為了加速即席查詢的分析效率,在我們的Hadoop集群上安裝部署了Spark Server,並且與我們的Hive數據倉庫共享元數據。也就是說,我們的用戶即可以通過HiveServer2使用Hive SQL執行MapReduce分析數據,也可以使用SparkServer使用Spark SQL(Hive SQL)執行Spark Application分析數據。
兩者除去MapReduce和Spark Application計算模式的不同之外,Spark Server的優勢在於它的Container進程是常駐的,也就是說它的計算資源是預留的,接收到SQL語句之后可以立即執行,響應速度更加迅速。
既然Spark Server和HiveServer2共享元數據,我們應該能夠在SQL層面最大限度地屏蔽兩者之間的差異。雖然Spark官方聲稱兼容大多數Hive SQL語句,但實際使用當中卻經常出現各種異常。
本文所要討論的就是Spark SQL使用Hive內建函數json_tuple的異常問題。
我們還是借用“Hive JSON數據處理的一點探索”中的示例數據表來說明問題。
(1)通過HiveServer2來執行Hive SQL語句;

(2)通過Spark Server來執行Hive SQL語句;

終端異常信息為:Error: java.lang.ClassNotFoundException: json_tuple (state=,code=0)
Spark Server日志輸出為:

懷疑的問題為找不到相應的jar包,其實實際問題是UDF解析類名錯誤,json_tuple為函數名稱,其對應的類名應為org.apache.hadoop.hive.ql.udf.generic.GenericUDTFJSONTuple。
這個異常直接影響到我們使用Hive UDF json_tuple通過Spark Server分析JSON數據。
方案
為了達到“Hive JSON數據處理的一點探索”中數據表myjson最后的查詢效果,我們需要使用Hive UDF get_json_object來實現,如下:

由get_tuple和func.json_array結合使用的方案變為get_json_object和func.json_array結合使用的方案。可以看出這種方案雖然繁雜,但可以應對實際問題。