Java通過Hadoop提供的API訪問HDFS不算困難,但針對其上文件的計算就比較麻煩。比如分組、過濾、排序等計算,用java來實現都比較複雜。集算器esproc能很好地協助java解決計算問題,同時也封裝了HDFS的訪問,藉助esproc可以讓java加強HDFS上文件的計算能力,結構化半結構....
Java通過Hadoop提供的API訪問HDFS不算困難,但針對其上文件的計算就比較麻煩。比如分組、過濾、排序等計算,用java來實現都比較複雜。集算器esproc能很好地協助java解決計算問題,同時也封裝了HDFS的訪問,藉助esproc可以讓java加強HDFS上文件的計算能力,結構化半結構化數據計算都可以輕鬆完成。下麵我們通過例子來看一下具體作法。
HDFS中的文本文件employee.gz中保存了員工數據。我們要讀取員工信息,從中找出1981年1月1日(含)之後出生的女員工。文本文件在HDFS中以gzip方式壓縮,並且無法一次裝入記憶體。
文本文件empolyee.gz的數據如下:
EID NAME SURNAME GENDER STATE BIRTHDAY HIREDATE DEPT SALARY
1 Rebecca Moore F California 1974-11-20 2005-03-11 R&D 7000
2 Ashley Wilson F New York 1980-07-19 2008-03-16 Finance 11000
3 Rachel Johnson F New Mexico 1970-12-17 2010-12-01 Sales 9000
4 Emily Smith F Texas 1985-03-07 2006-08-15 HR 7000
5 Ashley Smith F Texas 1975-05-13 2004-07-30 R&D 16000
6 Matthew Johnson M California 1984-07-07 2005-07-07 Sales 11000
7 Alexis Smith F Illinois 1972-08-16 2002-08-16 Sales 9000
8 Megan Wilson F California 1979-04-19 1984-04-19 Marketing 11000
9 Victoria Davis F Texas 1983-12-07 2009-12-07 HR 3000
10 Ryan Johnson M Pennsylvania 1976-03-12 2006-03-12 R&D 13000
11 Jacob Moore M Texas 1974-12-16 2004-12-16 Sales 12000
12 Jessica Davis F New York 1980-09-11 2008-09-11 Sales 7000
13 Daniel Davis M Florida 1982-05-14 2010-05-14 Finance 10000
…
實現的思路是:用Java程式調用集算器腳本,讀取和計算數據,之後將結果以ResultSet的方式返回給Java程式。
首先,要在集算器的集成開發環境中編寫和調試程式,準備工作是將Hadoop核心包及配置包複製到“集算器安裝目錄\esProc\lib”中,如:commons-configuration-1.6.jar、commons-lang-2.4.jar、hadoop-core-1.0.4.jar(Hadoop1.0.4)。
由於集算器支持動態表達式解析和求值,使得Java程式可以像使用sql那樣,靈活的過濾HDFS文件中的數據。例如,我們需要查詢1981年1月1日(含)之後出生的女員工,esProc程式可以從外部獲得一個輸入參數“where”作為條件,如下圖:
where是個字串,取值是:BIRTHDAY>=date(1981,1,1) && GENDER==”F”。
集算器esProc代碼如下:
A1:定義一個HDFS文件對象游標,第一行是標題,欄位分隔符預設是tab。壓縮方式由文件尾碼決定,這裡是gzip格式,集算器也支持其他壓縮方式。UTF-8是字元集,預設使用jvm的字元集。
A2:按照條件過濾游標。這裡使用巨集來實現動態解析表達式,其中的where就是傳入參數。集算器將先計算${…}里的表達式,將計算結果作為巨集字元串值替換${…}之後解釋執行。這個例子中最終執行的是:=A1.select(BIRTHDAY>=date(1981,1,1) && GENDER==”F”)。
A3:返回游標。
過濾條件發生變化時不用改變代碼,只需改變where參數即可。例如,條件變為:查詢1981年1月1日(含)之後出生的女員工,或者NAME+SURNAME等於”RebeccaMoore”的員工。Where的參數值可以寫為:BIRTHDAY>=date(1981,1,1) && GENDER==”F” || NAME+SURNAME==”RebeccaMoore”。
在Java程式中使用esProc JDBC調用這段程式獲得結果的代碼如下:(將上述esProc程式保存為test.dfx,並把HDFS需要的Hadoop的jar包放到java的classpath中):
//建立esProc jdbc連接
Class.forName(“com.esproc.jdbc.InternalDriver”);
con= DriverManager.getConnection(“jdbc:esproc:local://”);
//調用esProc 程式(存儲過程),其中test是dfx的文件名
st =(com.esproc.jdbc.InternalCStatement)con.prepareCall(“call test(?)”);
//設置參數
st.setObject(1,” BIRTHDAY>=date(1981,1,1) && GENDER==\”F\” ||NAME+SURNAME==\”RebeccaMoore\”");//參數就是動態的過濾條件
//執行esProc存儲過程
st.execute();
//獲取結果集:符合條件的員工集合
ResultSet set = st.getResultSet();