2015-03-18 70 views
0

我正在編寫自定義InputFormat(具體來說,是org.apache.hadoop.mapred.FileInputFormat的一個子類),OutputFormat和SerDe,以便通過Apache Hive讀取二進制文件。 並非二進制文件中的所有記錄都具有相同的大小自定義InputFormat.getSplits()永遠不會在Hive中調用

我發現Hive的默認InputFormat,CombineHiveInputFormat沒有將getSplits委派給我自定義的InputFormat實現,這會導致所有輸入文件在常規的128MB邊界上被拆分。問題在於這個分割可能在記錄的中間,所以除第一個之外的所有分割很可能看起來具有損壞的數據。

我已經找到了一些解決方法,但我不滿意他們中的任何一個。

一個解決辦法是要做到:

set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat; 

當使用HiveInputFormatCombineHiveInputFormat,以getSplits呼叫被正確地委託給我的InputFormat,一切都很好。不過,我想讓我的InputFormat,OutputFormat等可以輕鬆地提供給其他用戶,所以我寧願不必去經歷這個。另外,如果可能,我希望能夠利用組合分割。

另一個解決方法是創建一個StorageHandler。但是,我寧願不這樣做,因爲這會使StorageHandler支持的所有表非本機(因此所有減法器都寫入到一個文件中,不能將LOAD DATA放入表中)以及其他我想從本機保留的優點表)。

最後,我可以有我的InputFormat實現CombineHiveInputFormat.AvoidSplitCombination繞過最CombineHiveInputFormat的,但是這僅僅是在蜂巢1.0可用,我想我的代碼與早期版本的蜂巢(至少回到0.12)的工作。

我在蜂巢bug跟蹤系統提交一票在這裏,如果這種行爲是無意的:https://issues.apache.org/jira/browse/HIVE-9771

有沒有人寫了一個自定義的FileInputFormat,對於具有蜂巢可以取代getSplits?是否有任何麻煩讓蜂房將呼叫委託給getSplits,你必須克服?

回答

1

通常在這種情況下,您只需保留分割,以便您可以獲取塊的數據位置,並讓您的RecordReader瞭解如何從塊(分割)中的第一條記錄開始讀取並讀取下一個阻止最終記錄不會在分割結束時結束。這需要一些遠程讀取,但這是正常的,通常非常小。

TextInputFormat/LineRecordReader是否這樣做 - 它使用換行符來劃分記錄,因此記錄可以跨越兩個塊。它將遍歷分割中的第一條記錄,而不是從第一個字符開始,在最後一條記錄中,如果需要讀取完整數據,它將讀入下一個塊。

Where LineRecordReader starts the split by seeking past the current partial record.

Where LineRecordReader ends the split by reading past the end of the current block.

希望幫助直接的自定義代碼的設計。

+0

這已經爲我澄清了很多。謝謝!儘管直到現在我還沒有看到這篇文檔,但這也是對這個主題的有用閱讀:http://wiki.apache。組織/ Hadoop的/ HadoopMapReduce – llovett 2015-03-20 23:41:46