Hadoop學習筆記—20.網站日誌分析項目案例

1.1 項目來源

  本次要實踐的數據日誌來源於國內某技術學習論壇,該論壇由某培訓機構主辦,匯聚了衆多技術學習者,天天都有人發帖、回帖,如圖1所示。php

圖1 項目來源網站-技術學習論壇html

  本次實踐的目的就在於經過對該技術論壇的apache common日誌進行分析,計算該論壇的一些關鍵指標,供運營者進行決策時參考。java

PS:開發該系統的目的是爲了獲取一些業務相關的指標,這些指標在第三方工具中沒法得到的;mysql

1.2 數據狀況 

  該論壇數據有兩部分:sql

  (1)歷史數據約56GB,統計到2012-05-29。這也說明,在2012-05-29以前,日誌文件都在一個文件裏邊,採用了追加寫入的方式。shell

  (2)自2013-05-30起,天天生成一個數據文件,約150MB左右。這也說明,從2013-05-30以後,日誌文件再也不是在一個文件裏邊。數據庫

  圖2展現了該日誌數據的記錄格式,其中每行記錄有5部分組成:訪問者IP、訪問時間、訪問資源、訪問狀態(HTTP狀態碼)、本次訪問流量。apache

圖2 日誌記錄數據格式編程

2、關鍵指標KPI

2.1 瀏覽量PV

  (1)定義:頁面瀏覽量即爲PV(Page View),是指全部用戶瀏覽頁面的總和,一個獨立用戶每打開一個頁面就被記錄1 次。數組

  (2)分析:網站總瀏覽量,能夠考覈用戶對於網站的興趣,就像收視率對於電視劇同樣。可是對於網站運營者來講,更重要的是,每一個欄目下的瀏覽量。

  計算公式:記錄計數,從日誌中獲取訪問次數,又能夠細分爲各個欄目下的訪問次數。

2.2 註冊用戶數

  該論壇的用戶註冊頁面爲member.php,而當用戶點擊註冊時請求的又是member.php?mod=register的url。

  計算公式:對訪問member.php?mod=register的url,計數。

2.3 IP數

  (1)定義:一天以內,訪問網站的不一樣獨立 IP 個數加和。其中同一IP不管訪問了幾個頁面,獨立IP 數均爲1。

  (2)分析:這是咱們最熟悉的一個概念,不管同一個IP上有多少電腦,或者其餘用戶,從某種程度上來講,獨立IP的多少,是衡量網站推廣活動好壞最直接的數據。

  計算公式:對不一樣的訪問者ip,計數

2.4 跳出率

  (1)定義:只瀏覽了一個頁面便離開了網站的訪問次數佔總的訪問次數的百分比,即只瀏覽了一個頁面的訪問次數 / 所有的訪問次數彙總。

  (2)分析:跳出率是很是重要的訪客黏性指標,它顯示了訪客對網站的興趣程度:跳出率越低說明流量質量越好,訪客對網站的內容越感興趣,這些訪客越多是網站的有效用戶、忠實用戶。

PS:該指標也能夠衡量網絡營銷的效果,指出有多少訪客被網絡營銷吸引到宣傳產品頁或網站上以後,又流失掉了,能夠說就是煮熟的鴨子飛了。好比,網站在某媒體上打廣告推廣,分析從這個推廣來源進入的訪客指標,其跳出率能夠反映出選擇這個媒體是否合適,廣告語的撰寫是否優秀,以及網站入口頁的設計是否用戶體驗良好。

  計算公式:①統計一天內只出現一條記錄的ip,稱爲跳出數;②跳出數/PV;

2.5 板塊熱度排行榜

  (1)定義:版塊的訪問狀況排行。

  (2)分析:鞏固熱點版塊成績,增強冷清版塊建設。同時對學科建設也有影響。

  計算公式:按訪問次數統計排序;

3、開發步驟

3.0 須要用到的技術

  (1)Linux Shell編程

  (2)HDFS、MapReduce

  (3)HBase、Hive、Sqoop框架

3.1 上傳日誌文件至HDFS

  把日誌數據上傳到HDFS中進行處理,能夠分爲如下幾種狀況:

  (1)若是是日誌服務器數據較小、壓力較小,能夠直接使用shell命令把數據上傳到HDFS中;

  (2)若是是日誌服務器數據較大、壓力較大,使用NFS在另外一臺服務器上上傳數據;

  (3)若是日誌服務器很是多、數據量大,使用flume進行數據處理;

3.2 數據清洗

  使用MapReduce對HDFS中的原始數據進行清洗,以便後續進行統計分析;

3.3 統計分析

  使用Hive對清洗後的數據進行統計分析;

3.4 分析結果導入MySQL

  使用Sqoop把Hive產生的統計結果導出到mysql中;

3.5 提供視圖工具

  提供視圖工具供用戶使用,指標查詢mysql、明細則查詢Hbase;

4、表結構設計

4.1 MySQL表結構設計

  這裏使用MySQL存儲關鍵指標的統計分析結果。

4.2 HBase表結構設計

  這裏使用HBase存儲明細日誌,可以利用ip、時間查詢。

2、數據清洗

1、數據狀況分析

1.1 數據狀況回顧

  該論壇數據有兩部分:

  (1)歷史數據約56GB,統計到2012-05-29。這也說明,在2012-05-29以前,日誌文件都在一個文件裏邊,採用了追加寫入的方式。

  (2)自2013-05-30起,天天生成一個數據文件,約150MB左右。這也說明,從2013-05-30以後,日誌文件再也不是在一個文件裏邊。

  圖1展現了該日誌數據的記錄格式,其中每行記錄有5部分組成:訪問者IP、訪問時間、訪問資源、訪問狀態(HTTP狀態碼)、本次訪問流量。

log

圖1 日誌記錄數據格式

  本次使用數據來自於兩個2013年的日誌文件,分別爲access_2013_05_30.log與access_2013_05_31.log,下載地址爲:http://pan.baidu.com/s/1pJE7XR9

1.2 要清理的數據

  (1)根據前一篇的關鍵指標的分析,咱們所要統計分析的均不涉及到訪問狀態(HTTP狀態碼)以及本次訪問的流量,因而咱們首先能夠將這兩項記錄清理掉;

  (2)根據日誌記錄的數據格式,咱們須要將日期格式轉換爲日常所見的普通格式如20150426這種,因而咱們能夠寫一個類將日誌記錄的日期進行轉換;

  (3)因爲靜態資源的訪問請求對咱們的數據分析沒有意義,因而咱們能夠將"GET /staticsource/"開頭的訪問記錄過濾掉,又由於GET和POST字符串對咱們也沒有意義,所以也能夠將其省略掉;

2、數據清洗過程

2.1 按期上傳日誌至HDFS

  首先,把日誌數據上傳到HDFS中進行處理,能夠分爲如下幾種狀況:

  (1)若是是日誌服務器數據較小、壓力較小,能夠直接使用shell命令把數據上傳到HDFS中;

  (2)若是是日誌服務器數據較大、壓力較大,使用NFS在另外一臺服務器上上傳數據;

  (3)若是日誌服務器很是多、數據量大,使用flume進行數據處理;

  這裏咱們的實驗數據文件較小,所以直接採用第一種Shell命令方式。又由於日誌文件時天天產生的,所以須要設置一個定時任務,在次日的1點鐘自動將前一天產生的log文件上傳到HDFS的指定目錄中。因此,咱們經過shell腳本結合crontab建立一個定時任務techbbs_core.sh,內容以下:

#!/bin/sh

#step1.get yesterday format string
yesterday=$(date --date='1 days ago' +%Y_%m_%d)
#step2.upload logs to hdfs
hadoop fs -put /usr/local/files/apache_logs/access_${yesterday}.log /project/techbbs/data

  結合crontab設置爲天天1點鐘自動執行的按期任務:crontab -e,內容以下(其中1表明天天1:00,techbbs_core.sh爲要執行的腳本文件):

* 1 * * * techbbs_core.sh

  驗證方式:經過命令 crontab -l 能夠查看已經設置的定時任務

2.2 編寫MapReduce程序清理日誌

  (1)編寫日誌解析類對每行記錄的五個組成部分進行單獨的解析

複製代碼
    static class LogParser {
        public static final SimpleDateFormat FORMAT = new SimpleDateFormat(
                "d/MMM/yyyy:HH:mm:ss", Locale.ENGLISH);
        public static final SimpleDateFormat dateformat1 = new SimpleDateFormat(
                "yyyyMMddHHmmss");/**
         * 解析英文時間字符串
         * 
         * @param string
         * @return
         * @throws ParseException
         */private Date parseDateFormat(String string) {
            Date parse = null;
            try {
                parse = FORMAT.parse(string);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return parse;
        }

        /**
         * 解析日誌的行記錄
         * 
         * @param line
         * @return 數組含有5個元素,分別是ip、時間、url、狀態、流量
         */public String[] parse(String line) {
            String ip = parseIP(line);
            String time = parseTime(line);
            String url = parseURL(line);
            String status = parseStatus(line);
            String traffic = parseTraffic(line);

            return new String[] { ip, time, url, status, traffic };
        }

        private String parseTraffic(String line) {
            final String trim = line.substring(line.lastIndexOf("\"") + 1)
                    .trim();
            String traffic = trim.split(" ")[1];
            return traffic;
        }

        private String parseStatus(String line) {
            final String trim = line.substring(line.lastIndexOf("\"") + 1)
                    .trim();
            String status = trim.split(" ")[0];
            return status;
        }

        private String parseURL(String line) {
            final int first = line.indexOf("\"");
            final int last = line.lastIndexOf("\"");
            String url = line.substring(first + 1, last);
            return url;
        }

        private String parseTime(String line) {
            final int first = line.indexOf("[");
            final int last = line.indexOf("+0800]");
            String time = line.substring(first + 1, last).trim();
            Date date = parseDateFormat(time);
            return dateformat1.format(date);
        }

        private String parseIP(String line) {
            String ip = line.split("- -")[0].trim();
            return ip;
        }
    }
複製代碼

  (2)編寫MapReduce程序對指定日誌文件的全部記錄進行過濾

  Mapper類:

複製代碼
        static class MyMapper extends
            Mapper<LongWritable, Text, LongWritable, Text> {
        LogParser logParser = new LogParser();
        Text outputValue = new Text();

        protected void map(
                LongWritable key,
                Text value,
                org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, LongWritable, Text>.Context context)
                throws java.io.IOException, InterruptedException {
            final String[] parsed = logParser.parse(value.toString());

            // step1.過濾掉靜態資源訪問請求if (parsed[2].startsWith("GET /static/")
                    || parsed[2].startsWith("GET /uc_server")) {
                return;
            }
            // step2.過濾掉開頭的指定字符串if (parsed[2].startsWith("GET /")) {
                parsed[2] = parsed[2].substring("GET /".length());
            } else if (parsed[2].startsWith("POST /")) {
                parsed[2] = parsed[2].substring("POST /".length());
            }
            // step3.過濾掉結尾的特定字符串if (parsed[2].endsWith(" HTTP/1.1")) {
                parsed[2] = parsed[2].substring(0, parsed[2].length()
                        - " HTTP/1.1".length());
            }
            // step4.只寫入前三個記錄類型項
            outputValue.set(parsed[0] + "\t" + parsed[1] + "\t" + parsed[2]);
            context.write(key, outputValue);
        }
    }
複製代碼

  Reducer類:

複製代碼
    static class MyReducer extends
            Reducer<LongWritable, Text, Text, NullWritable> {
        protected void reduce(
                LongWritable k2,
                java.lang.Iterable<Text> v2s,
                org.apache.hadoop.mapreduce.Reducer<LongWritable, Text, Text, NullWritable>.Context context)
                throws java.io.IOException, InterruptedException {
            for (Text v2 : v2s) {
                context.write(v2, NullWritable.get());
            }
        };
    }
複製代碼

  (3)LogCleanJob.java的完整示例代碼

  View Code

  (4)導出jar包,並將其上傳至Linux服務器指定目錄中

2.3 按期清理日誌至HDFS

  這裏咱們改寫剛剛的定時任務腳本,將自動執行清理的MapReduce程序加入腳本中,內容以下:

#!/bin/sh

#step1.get yesterday format string
yesterday=$(date --date='1 days ago' +%Y_%m_%d)
#step2.upload logs to hdfs
hadoop fs -put /usr/local/files/apache_logs/access_${yesterday}.log /project/techbbs/data
#step3.clean log data
hadoop jar /usr/local/files/apache_logs/mycleaner.jar /project/techbbs/data/access_${yesterday}.log /project/techbbs/cleaned/${yesterday}

  這段腳本的意思就在於天天1點將日誌文件上傳到HDFS後,執行數據清理程序對已存入HDFS的日誌文件進行過濾,並將過濾後的數據存入cleaned目錄下。 

2.4 定時任務測試

  (1)由於兩個日誌文件是2013年的,所以這裏將其名稱改成2015年當天以及前一天的,以便這裏可以測試經過。

  (2)執行命令:techbbs_core.sh 2014_04_26

  控制檯的輸出信息以下所示,能夠看到過濾後的記錄減小了不少:

15/04/26 04:27:20 INFO input.FileInputFormat: Total input paths to process : 1
15/04/26 04:27:20 INFO util.NativeCodeLoader: Loaded the native-hadoop library
15/04/26 04:27:20 WARN snappy.LoadSnappy: Snappy native library not loaded
15/04/26 04:27:22 INFO mapred.JobClient: Running job: job_201504260249_0002
15/04/26 04:27:23 INFO mapred.JobClient: map 0% reduce 0%
15/04/26 04:28:01 INFO mapred.JobClient: map 29% reduce 0%
15/04/26 04:28:07 INFO mapred.JobClient: map 42% reduce 0%
15/04/26 04:28:10 INFO mapred.JobClient: map 57% reduce 0%
15/04/26 04:28:13 INFO mapred.JobClient: map 74% reduce 0%
15/04/26 04:28:16 INFO mapred.JobClient: map 89% reduce 0%
15/04/26 04:28:19 INFO mapred.JobClient: map 100% reduce 0%
15/04/26 04:28:49 INFO mapred.JobClient: map 100% reduce 100%
15/04/26 04:28:50 INFO mapred.JobClient: Job complete: job_201504260249_0002
15/04/26 04:28:50 INFO mapred.JobClient: Counters: 29
15/04/26 04:28:50 INFO mapred.JobClient: Job Counters 
15/04/26 04:28:50 INFO mapred.JobClient: Launched reduce tasks=1
15/04/26 04:28:50 INFO mapred.JobClient: SLOTS_MILLIS_MAPS=58296
15/04/26 04:28:50 INFO mapred.JobClient: Total time spent by all reduces waiting after reserving slots (ms)=0
15/04/26 04:28:50 INFO mapred.JobClient: Total time spent by all maps waiting after reserving slots (ms)=0
15/04/26 04:28:50 INFO mapred.JobClient: Launched map tasks=1
15/04/26 04:28:50 INFO mapred.JobClient: Data-local map tasks=1
15/04/26 04:28:50 INFO mapred.JobClient: SLOTS_MILLIS_REDUCES=25238
15/04/26 04:28:50 INFO mapred.JobClient: File Output Format Counters 
15/04/26 04:28:50 INFO mapred.JobClient: Bytes Written=12794925
15/04/26 04:28:50 INFO mapred.JobClient: FileSystemCounters
15/04/26 04:28:50 INFO mapred.JobClient: FILE_BYTES_READ=14503530
15/04/26 04:28:50 INFO mapred.JobClient: HDFS_BYTES_READ=61084325
15/04/26 04:28:50 INFO mapred.JobClient: FILE_BYTES_WRITTEN=29111500
15/04/26 04:28:50 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=12794925
15/04/26 04:28:50 INFO mapred.JobClient: File Input Format Counters 
15/04/26 04:28:50 INFO mapred.JobClient: Bytes Read=61084192
15/04/26 04:28:50 INFO mapred.JobClient: Map-Reduce Framework
15/04/26 04:28:50 INFO mapred.JobClient: Map output materialized bytes=14503530
15/04/26 04:28:50 INFO mapred.JobClient: Map input records=548160
15/04/26 04:28:50 INFO mapred.JobClient: Reduce shuffle bytes=14503530
15/04/26 04:28:50 INFO mapred.JobClient: Spilled Records=339714
15/04/26 04:28:50 INFO mapred.JobClient: Map output bytes=14158741
15/04/26 04:28:50 INFO mapred.JobClient: CPU time spent (ms)=21200
15/04/26 04:28:50 INFO mapred.JobClient: Total committed heap usage (bytes)=229003264
15/04/26 04:28:50 INFO mapred.JobClient: Combine input records=0
15/04/26 04:28:50 INFO mapred.JobClient: SPLIT_RAW_BYTES=133
15/04/26 04:28:50 INFO mapred.JobClient: Reduce input records=169857
15/04/26 04:28:50 INFO mapred.JobClient: Reduce input groups=169857
15/04/26 04:28:50 INFO mapred.JobClient: Combine output records=0
15/04/26 04:28:50 INFO mapred.JobClient: Physical memory (bytes) snapshot=154001408
15/04/26 04:28:50 INFO mapred.JobClient: Reduce output records=169857
15/04/26 04:28:50 INFO mapred.JobClient: Virtual memory (bytes) snapshot=689442816
15/04/26 04:28:50 INFO mapred.JobClient: Map output records=169857
Clean process success!

  (3)經過Web接口查看HDFS中的日誌數據:

  存入的未過濾的日誌數據:/project/techbbs/data/

  存入的已過濾的日誌數據:/project/techbbs/cleaned/

 3、統計分析

1、藉助Hive進行統計

1.1 準備工做:創建分區表

HIVE

  爲了可以藉助Hive進行統計分析,首先咱們須要將清洗後的數據存入Hive中,那麼咱們須要先創建一張表。這裏咱們選擇分區表,以日期做爲分區的指標,建表語句以下:(這裏關鍵之處就在於肯定映射的HDFS位置,我這裏是/project/techbbs/cleaned即清洗後的數據存放的位置)

hive>CREATE EXTERNAL TABLE techbbs(ip string, atime string, url string) PARTITIONED BY (logdate string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '/project/techbbs/cleaned';

  創建了分區表以後,就須要增長一個分區,增長分區的語句以下:(這裏主要針對20150425這一天的日誌進行分區)

hive>ALTER TABLE techbbs ADD PARTITION(logdate='2015_04_25') LOCATION '/project/techbbs/cleaned/2015_04_25';  

  有關分區表的詳細介紹此處再也不贅述,若有不明白之處能夠參考本筆記系列之17-Hive框架學習一文。

1.2 使用HQL統計關鍵指標

  (1)關鍵指標之一:PV量

  頁面瀏覽量即爲PV(Page View),是指全部用戶瀏覽頁面的總和,一個獨立用戶每打開一個頁面就被記錄1 次。這裏,咱們只須要統計日誌中的記錄個數便可,HQL代碼以下:

hive>CREATE TABLE techbbs_pv_2015_04_25 AS SELECT COUNT(1) AS PV FROM techbbs WHERE logdate='2015_04_25';

  

  (2)關鍵指標之二:註冊用戶數

  該論壇的用戶註冊頁面爲member.php,而當用戶點擊註冊時請求的又是member.php?mod=register的url。所以,這裏咱們只須要統計出日誌中訪問的URL是member.php?mod=register的便可,HQL代碼以下:

hive>CREATE TABLE techbbs_reguser_2015_04_25 AS SELECT COUNT(1) AS REGUSER FROM techbbs WHERE logdate='2015_04_25' AND INSTR(url,'member.php?mod=register')>0;  

  

  (3)關鍵指標之三:獨立IP數

  一天以內,訪問網站的不一樣獨立 IP 個數加和。其中同一IP不管訪問了幾個頁面,獨立IP 數均爲1。所以,這裏咱們只須要統計日誌中處理的獨立IP數便可,在SQL中咱們能夠經過DISTINCT關鍵字,在HQL中也是經過這個關鍵字:

hive>CREATE TABLE techbbs_ip_2015_04_25 AS SELECT COUNT(DISTINCT ip) AS IP FROM techbbs WHERE logdate='2015_04_25';

 

  

  (4)關鍵指標之四:跳出用戶數

  只瀏覽了一個頁面便離開了網站的訪問次數,即只瀏覽了一個頁面便再也不訪問的訪問次數。這裏,咱們能夠經過用戶的IP進行分組,若是分組後的記錄數只有一條,那麼即爲跳出用戶。將這些用戶的數量相加,就得出了跳出用戶數,HQL代碼以下:

hive>CREATE TABLE techbbs_jumper_2015_04_25 AS SELECT COUNT(1) AS jumper FROM (SELECT COUNT(ip) AS times FROM techbbs WHERE logdate='2015_04_25' GROUP BY ip HAVING times=1) e;

  

PS:跳出率是指只瀏覽了一個頁面便離開了網站的訪問次數佔總的訪問次數的百分比,即只瀏覽了一個頁面的訪問次數 / 所有的訪問次數彙總。這裏,咱們能夠將這裏得出的跳出用戶數/PV數便可獲得跳出率。

  (5)將全部關鍵指標放入一張彙總表中以便於經過Sqoop導出到MySQL

  爲了方便經過Sqoop統一導出到MySQL,這裏咱們藉助一張彙總表將剛剛統計到的結果整合起來,經過錶鏈接結合,HQL代碼以下:

hive>CREATE TABLE techbbs_2015_04_25 AS SELECT '2015_04_25', a.pv, b.reguser, c.ip, d.jumper FROM techbbs_pv_2015_04_25 a JOIN techbbs_reguser_2015_04_25 b ON 1=1 JOIN techbbs_ip_2015_04_25 c ON 1=1 JOIN techbbs_jumper_2015_04_25 d ON 1=1;

  

2、使用Sqoop導入到MySQL

2.1 準備工做:在MySQL中建立結果彙總表

  (1)Step1:建立一個新數據庫:techbbs

mysql> create database techbbs;
Query OK, 1 row affected (0.00 sec)

  (2)Step2:建立一張新數據表:techbbs_logs_stat

mysql> create table techbbs_logs_stat(
-> logdate varchar(10) primary key,
-> pv int,
-> reguser int,
-> ip int,
-> jumper int);
Query OK, 0 rows affected (0.01 sec)

2.2 導入操做:經過export命令

  (1)Step1:編寫導出命令

sqoop export --connect jdbc:mysql://hadoop-master:3306/techbbs --username root --password admin --table techbbs_logs_stat --fields-terminated-by '\001' --export-dir '/hive/techbbs_2015_04_25'

  這裏的--export-dir是指定的hive目錄下的彙總表所在位置,我這裏是/hive/techbbs_2015_04_25。

  (2)Step2:查看導出結果

  

3、改寫Linux定時任務

  剛剛咱們已經藉助Hive進行了關鍵指標的統計分析,而且藉助Sqoop導出到了MySQL,後續能夠藉助JSP或者ASP.NET開發指標瀏覽界面供決策者進行瀏覽分析。可是剛剛這些操做都是咱們本身手工操做的,咱們須要實現自動化的統計分析並導出,因而咱們改寫前一篇中提到的定時任務腳本文件。

3.1 加入分區、統計與導出操做

  重寫techbbs_core.sh文件,內容以下,step4~step8爲新增內容:

複製代碼
#!/bin/sh

......

#step4.alter hive table and then add partition
hive -e "ALTER TABLE techbbs ADD PARTITION(logdate='${yesterday}') LOCATION '/project/techbbs/cleaned/${yesterday}';"
#step5.create hive table everyday
hive -e "CREATE TABLE hmbbs_pv_${yesterday} AS SELECT COUNT(1) AS PV FROM hmbbs WHERE logdate='${yesterday}';"
hive -e "CREATE TABLE hmbbs_reguser_${yesterday} AS SELECT COUNT(1) AS REGUSER FROM hmbbs WHERE logdate='${yesterday}' AND INSTR(url,'member.php?mod=register')>0;"
hive -e "CREATE TABLE hmbbs_ip_${yesterday} AS SELECT COUNT(DISTINCT ip) AS IP FROM hmbbs WHERE logdate='${yesterday}';"
hive -e "CREATE TABLE hmbbs_jumper_${yesterday} AS SELECT COUNT(1) AS jumper FROM (SELECT COUNT(ip) AS times FROM hmbbs WHERE logdate='${yesterday}' GROUP BY ip HAVING times=1) e;"
hive -e "CREATE TABLE hmbbs_${yesterday} AS SELECT '${yesterday}', a.pv, b.reguser, c.ip, d.jumper FROM hmbbs_pv_${yesterday} a JOIN hmbbs_reguser_${yesterday} b ON 1=1 JOIN hmbbs_ip_${yesterday} c ON 1=1 JOIN hmbbs_jumper_${yesterday} d ON 1=1;"
#step6.delete hive tables
hive -e "drop table hmbbs_pv_${yesterday};"
hive -e "drop table hmbbs_reguser_${yesterday};"
hive -e "drop table hmbbs_ip_${yesterday};"
hive -e "drop table hmbbs_jumper_${yesterday};"
#step7.export to mysql
sqoop export --connect jdbc:mysql://hadoop-master:3306/techbbs --username root --password admin --table techbbs_logs_stat --fields-terminated-by '\001' --export-dir '/hive/hmbbs_${yesterday}'#step8.delete hive table
hive -e "drop table techbbs_${yesterday};"
複製代碼

3.2 分離日期獲取操做

  (1)改寫techbbs_core.sh腳本文件:

#!/bin/sh

#step1.get yesterday format string
#yesterday=`date --date='1 days ago' +%Y_%m_%d`
yesterday=$1

  這裏將日期字符串做爲參數傳入,將該步驟轉移到了其餘腳本文件中;

  (2)新增techbbs_daily.sh腳本文件:

#!/bin/sh

yesterday=`date --date='1 days ago' +%Y_%m_%d`
hmbbs_core.sh $yesterday

  這裏獲取日期並做爲參數傳遞給techbbs_core.sh文件;

  (3)改寫crontab定時任務配置:crontab -e

* 1 * * * /usr/local/files/apache_logs/techbbs_daily.sh

  這裏天天凌晨1點自動執行的就變爲techbbs_daily.sh腳本文件了;今後,咱們只需按期查看mysql數據庫中的彙總結果表進行瀏覽便可;

3.3 初始化任務操做

  當一個網站已經生成了不少天的日誌,而咱們的日誌分析系統卻一直沒上線,一直等到了某天才上線。這時,咱們須要寫一個初始化腳本任務,來對以前的天天的日誌進行統計分析與導出結果。這裏,咱們新增一個techbbs_init.sh腳本文件,內容以下:

複製代碼
#!/bin/sh

#step1.create external table in hive
hive -e "CREATE EXTERNAL TABLE techbbs(ip string, atime string, url string) PARTITIONED BY (logdate string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '/project/techbbs/cleaned';"

#step2.compute the days between start date and end date
s1=`date --date="$1"  +%s`
s2=`date +%s`
s3=$((($s2-$s1)/3600/24))

#step3.excute techbbs_core.sh $3 times
for ((i=$s3; i>0; i--))
do
  logdate=`date --date="$i days ago" +%Y_%m_%d`
  techbbs_core.sh $logdate
done
複製代碼

4、小結

  經過三部分的介紹,該網站的日誌分析工做基本完成,固然還有不少沒有完成的東西,可是大致上的思路已經明瞭,後續的工做只須要在此基礎上稍加分析便可完成。固然,咱們還能夠經過JSP或ASP.NET讀取MySQL或HBase中的分析結果表來開發關鍵指標查詢系統,供網站運營決策者進行查看和分析。

相關文章
相關標籤/搜索