本文來自O(shè)PPO互聯(lián)網(wǎng)技術(shù)團(tuán)隊,如需要轉(zhuǎn)載,請注明出處及作者。歡迎關(guān)注我們的公眾號:OPPO_tech hive設(shè)計之初,就被定位一款離線數(shù)倉產(chǎn)品,雖然Hortonworks喊出了Make Apache Hive 100x Faster的牛逼口號,也在上面做了大量的優(yōu)化,然而性能提升依舊不大。 而隨著OPPO數(shù)據(jù)量一步步的增多,動輒運行幾個小時的hive再也滿足不了交互查詢的需求,因此我們引入了presto,sql on hadoop陣營里的優(yōu)秀代表。主要適用于即席查詢。 然而事情往往木有那么簡單,很多分析師用慣了hql,遷移的成本很大,所以本著業(yè)務(wù)方都是美麗的上帝的原則。為了使用戶能平滑的將業(yè)務(wù)遷移到presto上,我們義無反顧跳入了presto兼容hive這個大坑中,接下來介紹下我們主要兼容工作。 presto兼容hive,總的來說需要解決如下幾點問題:
要完全解決這些問題無疑是費時費力,所以我們在presto和hive之上構(gòu)建一層路由層--功能是將查詢請求優(yōu)先提交到presto中查詢。若執(zhí)行錯誤,則路由到hive中。 當(dāng)然還是存在一定風(fēng)險,因為由于語義處理上的不同,相同的sql在presto和hive中可能會得到不同的結(jié)果。 語義上的修改Part 1: Key not present in mappresto處理map,若key不存在,會報錯,而hive會返回null。 Part 2: Cast as string由于presto中并沒有名為string的類型,出現(xiàn)若進(jìn)行cast as string這樣的轉(zhuǎn)換,或者表定義中有string類型會出現(xiàn)Unknown type 的錯誤。因此我們在ASTBuilder.java中把string替換為了varchar類型(實現(xiàn)了對sql語法樹的轉(zhuǎn)換) Part 3: 類型隱式轉(zhuǎn)換遷移過程中,在presto中經(jīng)常會出現(xiàn)類型不匹配的錯誤。核心原因就是hive會對數(shù)據(jù)類型做兼容性轉(zhuǎn)換。一開始考慮對運算符進(jìn)行重載,如添加以下函數(shù): 就能支持如下case: 然而這種方式需要對+,- ,* ,/ ,between ,in 等幾乎所有的運算符進(jìn)行重載,太繁瑣了。 因此我們換了一種思路:即隱式的插入一個CAST。相當(dāng)于把 select 1 = '1' 轉(zhuǎn)換成了 select 1 = cast('1' as int),從而在sql編譯的前端實現(xiàn)了轉(zhuǎn)換,兼容性上不會有任何問題。 hive視圖兼容presto和hive語義不同,自然hive定義的視圖presto不能訪問,但對一些簡單的視圖定義,如: 我們可以提供支持,方法也很簡單:即在presto讀取視圖定義(StatementAnalyzer.java)的時候,解析原始的sql定義的語句,轉(zhuǎn)換成presto的視圖結(jié)構(gòu)。 總結(jié)
當(dāng)然presto對于hive的兼容工作遠(yuǎn)不止這些,udtf,hive對null處理等等,涉及到方方面面的細(xì)節(jié),這也凸顯了統(tǒng)一的sql標(biāo)準(zhǔn)的重要性。 最后,重點來啦: OPPO互聯(lián)網(wǎng)運維云存儲團(tuán)隊急招多個崗位,歡迎對MongoDB內(nèi)核源碼、Wiredtiger存儲引擎、RocksDB存儲引擎、數(shù)據(jù)庫機(jī)房多活、數(shù)據(jù)鏈路同步系統(tǒng)、中間件、數(shù)據(jù)庫等有興趣的同學(xué)加入,一起參與OPPO百萬級高并發(fā)文檔數(shù)據(jù)庫研發(fā)。 工作地點:深圳 / 成都 聯(lián)系郵箱:yangyazhou@oppo.com(最好注明來源思否) |
|