Oracle Sql 轉 Spark SQL開發實踐中的思考與總結

實踐背景:

將一段存在五重子查詢嵌套與數據轉換計算的Oracle SP(Sql Procedure)用Spark SQL實現。並且採用Java進行開發(不能用最愛的Scala了。。。)
這段SQL的核心邏輯接近千行代碼,背後涉及到的關聯表接近10個。沒有文檔,沒有表ER圖可供參考。我更願將其定義爲傳統計算模型在大數據背景下的技術轉型,或說是升級。
在此將採用Spark SQL的sql開發模式,一般在Spark SQL開發環境下可以選擇使用sql(也就是sparkSession.sql(…))或者Spark API方式進行對應的業務開發,兩者各有優劣,詳細對比請查閱相關資料。

在此主要採用sql方式。

實現過程

1、業務背景學習
針對這樣的轉換,僅僅是針對SP去進行轉換是不行的,Oracle與Spark SQL在API層面還是有許多差別的,我們就稱之爲SQL兼容問題吧。在trouble shotting的時候如果能夠對業務背景有着一定的把握,可以減少很多不必要的損耗,讓調bug之路更加順暢。
而如果在沒有詳細文檔可供參考的情況下,向小夥伴請教就成了不二之選了。

2、SP代碼分析報告
拿到這樣一個複雜SP當然得看看是否可以進行模塊劃分啦,一般情況下都是可以的。這就像是代碼設計一樣,試着回想你有在企業級項目中看到過用高級語言寫的function長達500行代碼嗎?如果有,那我想這個項目的開發維護進程多半是坎坷的。
在對SP進行代碼層面觀察的時候發現幾個代碼模塊是有着極高相似度的,這個時候就可以考慮是否可以進行模板抽取進行復用了。
此階段形成的書面文檔於後續的開發具有一定的指導性作用。

3、業務細化回溯
針對以上分析報告當然是要請一起參與開發的小夥伴幫忙看看了,聚集團隊的力量探討改進不足的地方。就比如說在某個業務代碼模塊running在Oracle上是perfect的,但在Spark上卻有可能出現兼容或說是適用性問題,集中式與分佈式運算還是有挺大差別的。

4、代碼設計
經過了前面幾輪工作,對SP業務原貌有了更多的把握後就可以進入代碼設計階段了。在這個時候需要考慮scope的問題了;你的代碼設計僅僅針對的是這一個SP的轉換還是需要提供更多的擴展支持呢,SP會有變動的可能性嗎?設計沒有一個特定的標準,針對具體的業務背景和需求做出恰到好處的設計實在重中之重。這個時候設計模式相關成了必備的一個知識。

5、代碼實現
注意代碼開發風格,參考阿里代碼開發手冊。

6、測試
如果可以,搞個自動化測試檢測所有的cell數據是否和原來的SP能夠對上!僅憑人工檢查部分數據對上是不夠的。

踩過的坑

語法兼容問題
在這樣的SP中一般會涉及到各種系統函數的轉換操作,此時就得考慮在將SP上的代碼運用到Spark上是二者的Sql API或者相關語法是否兼容了。就比如說在Oracle上可以直接使用“+”運算符進行日期的遞增,而在Spark Sql直接用這種方法進行計算得到的就是null,在排查出問題後使用date_add()函數就解決了。通過這次的實踐來看:對應數據表cell上顯示爲null,而檢查代碼數據本應該是有值並且基本代碼邏輯沒問題的情況下,就應該考慮是否API兼容問題了。而在顯示爲null的情況下Spark不會報錯,這種問題出現若不是有着嚴密的測試是很難用肉眼去發現的。當然這種情況還是相對較少的,多數情況下的不兼容在運行階段就會報錯,如此SqlAnalysis錯誤就比較常見了。

sql代碼放哪裏
此處針對原有SP代碼有着大量的sql可以直接複用,同時爲了避免大段sql出現在java代碼塊中照成不必要的維護困難與sql侵入,此處將sql放在properties文件中,同時利用propertiesUtil工具類對這些sql進行初步解析處理;其實就是字符串處理了。

相關優化

將近五層的查詢嵌套盡然產生了五百多個stage,是catalyst不夠給力?

在採用Spark Sql方式進行轉換中需要將每一個子查詢進行tempView抽取,一個轉換過程中可能會產生幾十個tempView。且不說這種繁瑣的工作沒有太多技術含量並且容易出錯,光是創建tempView進行迭代計算的時候就已經在代碼層面造成了字面量浸染;名副其實的搬磚。當然,此處肯定是有着更好的解決方案,我想自身的代碼設計能力還是有很大的提升空間的。即使是搬磚,咋也不能用裸手去搬吧,開着剷車去搬效率也天差地別呀!

當然此處除了代碼設計層面,還有其他可優化的地方。除了基本的Spark Core相關優化,Spark Sql本身就對我們的Sql解析運行做了許多優化,比如DataSet的Kyro序列化、廣播小表、謂詞下推等等。其他相關優化可見:https://blog.csdn.net/qq_34901049/article/details/103515309

方法可行性反思

針對這個demo,其實各方面的問題還是挺多的。選擇大於努力,我相信所有技術的問題都會有解決方案;而在技術選型的問題上,如果我們能夠選用最適合的方案,是否會減少很多不必要的問題呢?換句話說,如果此處的目標是在大數據場景下將原本RDB集中式計算的數據升級遷移到分佈式計算架構。那麼此處採用Hive會不會更好呢?畢竟Spark作爲一個運算引擎,我們完全可以配置Hive on Spark實現基於內存爲主的高效數據處理。而另一方面,就目前的版本(Spark 2.2)來看,Spark Sql對於複雜嵌套子查詢似乎並沒有很好的支持,否則也不會出現一個個的tempView。

當然,對於Hive的轉換,也同樣有待進一步的實踐考證。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章