Hbase應用的一次錯誤處理

在實現《Hadoop高級編程》一書中第9章的一個例子:將HBase用於圖片管理系統中,遇到了一個很讓人頭疼的問題:FileNotFoundException。雖然異常很簡單,可是文件確實存在那了。因而開始了長時間的排錯之旅。java

該例子是將一堆小圖片文件合成一個大文件,並將各個小文件的位置索引存入HBase中。有一個DatedPhoto類,用於存放時間(long)以及圖片(byte[]);還有一個PhotoLocation類,用於存放位置(long)、時間(long)和文件名(String)。位置是小文件在大文件中的字節位置,文件名是合成的大文件名,按序號命名。PhotoLocation類還提供了toBytesfromBytes函數,用於將三種信息字節化後寫入HBase以及從HBase中讀出索引信息後還原成位置, 時間文件名 信息。其他爲寫入類,讀出類。總體很是簡單。編程

寫的時候徹底沒有問題,文件成功生成,HBase中保存了索引。可是讀取的時候,出現問題:一直報FileNotFoundException異常,而路徑並未出錯並且文件存在。數組

這究竟是怎麼一回事呢?由於用的是SequenceFile中的內部類ReaderWriter,而Hadoop 2.2.0的API中並無找到這兩個東西,便從源碼入手看看是否是這個類的問題。按照執行流程過了一遍,任何問題都沒發現。因爲錯誤定位在SequenceFile.Reader的構造函數中getFileStatus上,便從新寫了一個類測試FileSystem類的getFileStatus類,發現徹底沒有問題,不是這出的錯誤。函數

PhotoDataReader類是輔助讀出數據的類,被PhotoReader類調用。錯誤就定位在了該類的構造上。查看PhotoDataReader類構造函數,其功能就是接受參數,調用SequenceFile.Reader的構造函數。輸出PhotoDataReader接收到的參數:fileString)、userUUID)、confConfiguration),三者都沒問題,可是出現了一個很奇怪的現象:oop

執行測試

System.out.println("file:"+ _file + "sadasdsasdssssss");

時,後面的那一串字符串竟然不顯示!code

看來問題就出如今_file參數上面。可是無論怎麼輸出_file的值,的確就是我要的那個文件名的字符串。彷佛這是個根本就不該該出現的問題。而後輸出_file的字符串長度,明明只有1個字符的文件名,顯示的長度爲112!看來問題就在這!索引

問題究竟出如今哪呢?繼續向上找,發現參數是PhotoReader傳給它的;PhotoReader又經過讀取HBase中的索引記錄獲得後用PhotoLocationfromBytes函數獲得…… fromBytes函數?其實現的是將一個包含索引位置時間文件名的128位字符數組分開而後生成三個值。索引位置與時間均爲long型,字符數組均爲8位,沒有問題。可是文件名爲字符串,合成字符數組時用的length函數,可是還原時就把除索引位置與時間的16位排除後剩下的112位所有用來生成字符串了!生成字符串用Bytes.bytes()new String均沒法生成原長度的字符串。圖片

既然知道了緣由,解決也好辦了。要麼設個長度位,要麼用定長字符串,要麼乾脆在HBase分開存儲。看來,有時候報錯,問題每每出如今細節上,仔細思考每一處細節,能夠減小不少的排錯時間。至少此次我花了很多時間。字符串

相關文章
相關標籤/搜索