上篇文章中,練習了範例程式 wordcount的使用,以及學習如何操作 hdfs。接下來這個例子,增加了一點變化,要來分析apache2 web server的log記錄檔,計算每小時的存取次數。

以下使用 python,如果想要使用 java,可以參考這篇文章


實作分析

首先,要了解 apache2 web server記錄檔的格式長怎樣。可以參考官方的說法 ,也可以看看下面的例子。

apache2 web server 的檔案格式如下:

64.242.88.10 - - [07/Mar/2004:16:10:02 -0800] "GET /mailman/listinfo/hsdivision HTTP/1.1" 200 6291

這裡面包含了來源ip位置,時間以及http request資訊。

由於我們要算的是每小時的存取次數,ip位置與request資訊都可以拿掉,只留下時間,如下:

2004-03-07 T 16:00:00.000

所以要做的事情是:擷取框框中的時間字串,將分,秒清空為00,接著丟進hadoop算wordcount,等待結果


map-reduce範例程式

這是根據網路上的 python範例程式修改而成,有興趣可以參照這篇教學

mapper.py

reducer.py

範例 access.log檔案下載(已移除)

[更新]手邊沒有apache log的話,可以拿 NASA提供的 HTTP資料集做測試

連結:NASA-HTTP  (裡頭的時區是0400,需要改一下程式才能跑喔)


程式解說

擷取框框中的時間字串,並濾掉-0800

得到這樣子的輸出

07/Mar/2004:16:10:02

接著透過python的datetime module來做格式的轉換

表格中節錄幾個用到的符號:

Directive Meaning Example
%d Day of the month as a zero-padded decimal number. 01, 02, …, 31
%b Month as locale’s abbreviated name.
Jan, Feb, …, Dec (en_US);
Jan, Feb, …, Dez (de_DE)
%m Month as a zero-padded decimal number. 01, 02, …, 12
%Y Year with century as a decimal number. 1970, 1988, 2001, 2013
%H Hour (24-hour clock) as a zero-padded decimal number. 00, 01, …, 23
%M Minute as a zero-padded decimal number. 00, 01, …, 59
%S Second as a zero-padded decimal number. 00, 01, …, 59

為了要交給map-reduce去統計次數,必須要將每小時的資料修改成一樣

這裏輸出單位至小時,後面的分秒都設為0,並在後面加上一個1,結果如下:

2004-03-07 T 16:00:00.000    1

PS. 因為只是要統計次數,其實可以不要印出0,這邊只是參考網路上JAVA版本的作法,做相同的輸出

在執行hadoop map-reduce前,我們先執行看看python程式是否正確

$ cat access.log | python mapper.py | python reducer.py

在hadoop上進行運算

先將hadoop開起來


執行map-reduce

這邊我寫了一個script,並附上註解了,如果還是不清楚,可以參考hadoop streaming的說明

檔案存放在output資料夾下
Image 007


執行結果
打開result.dat檔案,就可以看到結果拉
Image 016


參考資料

Applied Big Data Analysis in the Real World with MapReduce and Hadoop

Python datetime