hive優化

最近使用hive一個多月下來(終於完成第一期數據分析遷移工作了),當時使用的0.8的版本(現在最新版本是0.8.1),一個多月下來收穫很多。從安裝環境、

調試、開發、業務理解、技術攻關、業務實現等,一一都體驗了一把!

總的來說,除了目前網上所介紹的常規hive使用和優化外。

因爲目前hive只支持0.20的相關版本,所以我們的環境還是使用的0.20版本的hadoop來進行搭建。
使用hive和hadoop是一種綜合能力的體現,之前我在使用的過程當中,還涉及到很多系統層面的問題。如果讓hive和hadoop結合的更緊密,個人認爲是從以下幾個角度進行:
第一:hive的類SQL語句本身進行調優
第二:就是hive的參數調優
第三:hadoop裏的hdfs的參數調優(存儲格式、壓縮格式、RPC調用、連接數控制)
第四:hadoop裏的map/reduce的調優(datanode間的數據傳輸、處理大小、每個child的相關JVM設置等)
第五:就是hadoop環境裏的網絡傳輸的調優(硬件環境)
第六:就是hdfs的存儲格式調優(文本格式、順序格式等)
第七:操作系統層面的磁盤I/O調優(多路複用等)
第八:操作系統層面的網絡調優(緩衝區大小、連接數放大等)
第九:操作系統層面的內存調優(虛擬內存設置、內存控制等)
第十:hadoop的容錯機制的掌握,因爲正常的運行到沒什麼,怕就是出現異常時,有相應的應對方案(調度器、隊列等)
第十一:hadoop的管理(包括datanode失效、namenode失效、加入或刪除datanode、負載均衡、集羣等)

另外網上更多的是基於SUN的JVM來搭建hadoop環境,但我在使用的過程中是用jrockit的JVM來搭建hadooop環境,主要是考慮到目前在jrockit 6.0的版本上性能比較強勁(體現在網絡傳輸、線程、GC回收等)。

另一方面是使用到了多種程序語言,如SQL(不過還是跟真正在數據庫的SQL語法有區別的)、java、python(還好之前有用過python做過開發)、shell等。
現在先說說hive,畢竟在這次的開發過程中,hive使用比例很大。關於hive其中有些參數的使用和搭配,目前我還在測試過程當中(幾個關鍵參數),以後再詳細講解。
hive個人覺得更適合做一些聚合場景的相關處理,其自定義函數UDAF更能體現這樣的一個特點。
關於UDF這種自定義函數比較適合做一些字段上的轉換處理,例如一個Text類型轉換成一個array類型;另外就是可以實現更爲豐富的解碼方式,如在URL中有些參數使用了UTF-8編碼或者GBK編碼的方式。
還支持自定義的map/reduce方式(相關關鍵字)。

/*mapjoin*/這種標識(這裏描述有誤,mapjoin是提供了一種提高join的方式)。
支持多種存儲格式,如:行格式、文件格式等,hdfs裏也支持多種存儲格式。
支持導入/導出數據,這裏需要提醒下,使用hive命令的導出,會把一行數據進行合併,也就看不出字段;所以一般都採用 hive -e 'select * from t' >> 123.txt這樣形式命令,才能使導出的字段由空格進行分割(後來驗證過,這是我的一個使用失誤,其實裏面還是有\001的符號,只是顯示的時候不顯示而已,所以兩種方式都適合)。
NULL和空值的區別,在hive的處理時需要注意(特別是與python這樣的腳本結合使用,另外還有在python中的字段切割問題)。

現在總結下hive不擅長的地方
因爲我這次的開發任務是將有些用SAS計算的任務遷移到hadoop上面進行數據分析,因爲SAS上有很多強勁的功能,在做數據分析時很有幫助;但在hive上面就沒有這樣的功能了。舉例如下:
SAS上有類似與遊標的概念的東東,可以操作記錄行,並對記錄裏一某個字段進行移動(如將某個字段移到前一條記錄上面)
SAS有排重功能(也就是根據幾個字段,去掉重複數據)
SAS可以輕鬆進行分組後,前取每個分組裏的前10條記錄
SAS不好的地方就是進行解碼轉換(如經過UTF-8或者GBK編碼的方式,這裏主要指的是URL裏,就比較麻煩)
常見場景等,另外還有幾種情況描述起來較爲複雜,這裏略之。

關於之前描述的前三種情況,如果只是簡單的用HIVE本身的SQL語句方式那是很難實現的,三種情況的共同點就是如何操作一行記錄。
hadoop裏有一種方式叫streaming,就是一行一行的讀取,然後通過腳本的方式進行處理,在這裏剛好hive是支持腳本的,所以可以用腳本來實現操作一行記錄(我這裏使用的是python腳本)
關於排重功能,在SAS實現的原理基本就是按照幾個關鍵字進行排序,然後進行排重處理(因爲排序之後,重複的數據肯定是在一起的,這樣做排重處理就比較方便了)。
所以在hive這邊,首先也是進行按幾個關鍵字排序,然後採用腳本方式進行去掉重複數據。
雖然腳本的運行時間比純java要慢,但是因爲腳本滿足了業務需求,所以運行慢的缺陷我們是可以忽略的,畢竟hive後期調優中,也有關鍵字的支持map、reduce。
關於如何用腳本進行取每個分組的前10條記錄(給一個簡單的業務場景,取每個地區(按上海、北京、深圳、廣州等)的銷售量前十名的業務員),由讀者自己可以思考下。
第四個場景,關於URL參數解碼問題,很簡單,就自定義一個UDF,然後通過java的方式來進行解決。這裏有個比較麻煩的地方就是如何區分出這個URL是用UTF-8編碼還是GBK編碼。

另補充兩點:

就是一個hiveSQL腳本,最好別太多SQL,不然會導致一些異常情況出現。最好進行拆分。如下:

1.sql

1_1.sql

1_2.sql

形式,這樣方便在shell裏進行控制。
第二個就是多看源碼(hadoop源碼、hive源碼),發現有些參數配置,都在程序裏,但文檔中並沒有體現。

這些就是大致使用下來的感覺,後續還有新的體驗,再增加吧!
如有不懂的地方,可以提問。

這裏是再次補充下這個項目有關hive的使用問題:

 首先是去重問題,後來經過反覆測試發現,map個數不能是多個,不然前一個split的最後一條記錄,與後一個split的第一條記錄,無法進行匹配去重。

所以當碰到這樣的問題時,MR的優勢將無法體現出來,目前採用的是最簡單的方法就是map個數和redce個數都設置成1

但是不知道MR其中有一種chain方式是否可行。

綜上所述,當碰到這種上下記錄有關聯的時候,如何利用MR這種模式,還是要好好琢磨和不斷的測試的。

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