實踐:使用 Apache Hadoop 處理日誌

簡介: 日誌是任何計算系統中一個必不可少的部分,支持從審計到錯誤管理等功能。隨着日誌的發展和日誌來源數量的不斷增加(比如在雲環境中),有必要提供一個可擴展的系統來高效處理日誌。這篇實踐將探討如何在典型 Linux 系統上使用 Apache Hadoop 來處理日誌。


日誌形態千差萬別,但隨着應用程序和基礎架構的發展,結果產生了大量對用戶有用的分佈式數據。從 Web 和郵件服務器到內核和引導日誌,許多現代的服務器擁有豐富的信息集。大量的分佈式數據是 Apache Hadoop 的完美應用,就像日誌文件(按時間排序的結構化文本數據)一樣。

您可以使用日誌處理來提取各種信息。其中最常用的一種用法是提取錯誤,或是對某個系統中的一些事件(比如登錄失敗)的發生次數進行計數。您還可以提取某些類型的性能數據,比如每秒連接數或每秒處理的事務數。其他有用的信息包括 Web 日誌中的站點訪問量(減少)的提取(映射)和構造。這一分析除了支持檢測文件訪問統計之外,還支持對惟一用戶訪問的檢測。

關於本文


這些練習將爲您提供以下幾方面的實踐:

  • 建立一個簡單的 Hadoop 環境並運行它
  • 與 Hadoop 文件系統 (HDFS) 進行交互
  • 編寫一個簡單的 MapReduce 應用程序
  • 編寫一個過濾的 Apache Pig 查詢
  • 編寫一個累計的 Pig 查詢

要從這些練習中獲得最大的益處,您應當掌握 Linux® 的基本應用知識。對虛擬設備有一些瞭解也有助於建立一個簡單的環境。

1.建立一個簡單的 Hadoop 環境並運行它

要建立 Hadoop 環境並運行它,有兩種方法。第一種是安裝 Hadoop 軟件,然後針對您的環境(最簡單的情況是一個單節點實例,其中所有的守護程序都在單個節點上運行)對其進行配置。參見 用 Hadoop 進行分佈式數據處理,第 1 部分:入門 以瞭解有關的詳細信息。

第二種(也是較爲簡單的一種)方法是通過使用 Cloudera 的 Hadoop Demo VM(包含一個 Linux 映像和一個預配置的 Hadoop 實例)。Cloudera 虛擬機 (VM) 運行於 VMware、基於 Kernel 的虛擬機或 Virtualbox 之上。

選擇一種方法,並完成安裝。然後,完成以下任務:

  • 通過發出一個 HDFS ls 命令來驗證 Hadoop 是否正在運行。
2. 與 HDFS 進行交互

HDFS 是一種專用的文件系統,用來管理一個 Hadoop 集羣內的數據和副本,並將它們分配給各個計算節點,以便高效處理它們。儘管 HDFS 是一種專用的文件系統,但它仍然可以實現許多典型的文件系統命令。要檢索 Hadoop 的幫助信息,可發出 hadoop dfs 命令。請執行以下任務:

  • 在 HDFS 內創建一個測試子目錄。
  • 使用 copyFromLocal 將一個文件從本地文件系統移動到 HDFS 子目錄中。
  • 對於額外的練習,請使用 hadoop dfs 命令查看 HDFS 內的文件。
3. 編寫一個簡單的 MapReduce 應用程序

編寫一個單詞數映射和縮減應用程序非常簡單。使用本文中演示的 Ruby 示例,開發一個 Python 映射和縮減應用程序,並在樣例數據集上運行它們。回想一下,Hadoop 對映射的輸出進行了排序,所以詞語很可能是連續的,這爲縮減程序 (reducer) 提供了一種有用的優化。


Pig 允許您構建一個簡單的、可轉換成 MapReduce 應用程序的腳本。在本練習中,您提取了所有的日誌條目(來自 /var/log/messages),這些日誌條目中包含單詞 kernel: 和單詞 terminating。

  • 創建一個根據預定義的標準提取所有日誌行的腳本。
  • 編寫一個聚合 Pig 查詢

日誌消息由 Linux 內核(比如 kerneldhclient)中的各種來源生成。在本例中,您需要找出生成日誌消息的各種來源,以及每個來源生成的日誌消息數量。

  • 創建一個對每個日誌來源生成的日誌消息數進行計數的腳本。習解決方案

具體的輸出取決於特定的 Hadoop 安裝和配置


清單 1. 在 HDFS 上執行一個 ls 操作
				
$ hadoop dfs -ls /
drwxrwxrwx    - hue       supergroup           0 2011-12-10 06:56 /tmp
drwxr-xr-x    - hue       supergroup           0 2011-12-08 05:20 /user
drwxr-xr-x    - mapred    supergroup           0 2011-12-08 10:06 /var
$

所顯示文件的多少取決於具體的使用。

練習 2 的解決方案:與 HDFS 進行交互

練習 2 中,您在 HDFS 內創建了一個子目錄,並將一個文件複製到這個子目錄中。請注意,您是通過將內核消息緩衝器移動到某個文件中來創建測試數據的。對於額外的練習,請使用 cat 命令(參見 清單 2)查看 HDFS 內的文件。


清單 2. 操作 HDFS
				
$ dmesg > kerndata
$ hadoop dfs -mkdir /test
$ hadoop dfs -ls /test
$ hadoop dfs -copyFromLocal kerndata /test/mydata
$ hadoop dfs -cat /test/mydata
Linux version 2.6.18-274-7.1.el5 ([email protected])...
...
e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
$

練習 3 的解決方案:編寫一個簡單的 MapReduce 應用程序


清單 3. 用 Python 編寫的映射應用程序
				
#!/usr/bin/env python

import sys

for line in sys.stdin:
    line = line.strip()
    words = line.split()
    for word in words:
        print '%s\t1' % word

提供了縮減應用程序。


清單 4. 用 Python 編寫的縮減應用程序
				
#!/usr/bin/env python

from operator import itemgetter
import sys

last_word = None
last_count = 0
cur_word = None

for line in sys.stdin:
    line = line.strip()

    cur_word, count = line.split('\t', 1)

    count = int(count)

    if last_word == cur_word:
        last_count += count
    else:
        if last_word:
           print '%s\t%s' % (last_word, last_count)
           last_count = count
        last_word = cur_word

if last_word == cur_word:
    print '%s\t%s' % (last_word, last_count)

說明了在 Hadoop 中調用 Python MapReduce 示例的流程。


清單 5. 使用 Hadoop 測試 Python MapReduce
				
$ hadoop jar /usr/lib/hadoop-0.20/contrib/streaming/hadoop-streaming-0.20.2-cdh3u2.jar \
  -file pymap.py -mapper pymap.py -file pyreduce.py -reducer pyreduce.py \
  -input /test/mydata -output /test/output
...
$ hadoop dfs -cat /test/output/part-00000
...
write	3
write-combining	2
wrong.	1
your	2
zone:	2
zonelists.	1
$

練習 4 的解決方案:編寫一個簡單的 Pig 查詢

練習 4 中,您提取了 /var/log/messages 日誌條目,該條目同時包含了單詞 kernel: 和單詞 terminating。在這種情況下,您可以在本地模式下使用 Pig 查詢本地文件(參見 清單 6)。將文件加載到一個 Pig 關係(日誌)中,過濾其內容,直到只剩下內核消息,然後過濾結果關係,以便獲得終止消息。


清單 6. 提取所有的內核日誌消息 + 終止日誌消息
				
$ pig -x local
grunt> log = LOAD '/var/log/messages';
grunt> logkern = FILTER log BY $0 MATCHES '.*kernel:.*';
grunt> logkernterm = FILTER logkern BY $0 MATCHES '.*terminating.*';
grunt> dump logkernterm
...
(Dec  8 11:08:48 localhost kernel: Kernel log daemon terminating.)
grunt>

練習 5 的解決方案:編寫一個聚合 Pig 查詢

練習 5 中,提取日誌來源和根據 /var/log/messages 獲得的日誌消息計數。在這種情況下,需要爲查詢創建一個腳本,並在 Pig 的本地模式下執行它。在 清單 7 中,您加載了文件,並使用空格作爲分隔符對輸入進行解析。隨後將已劃分界限的字符串字段分配給指定的元素。使用 GROUP 運算符根據消息來源對消息進行分組,然後使用 FOREACH 運算符和 COUNT 來聚合您的數據。


清單 7. /var/log/messages 的日誌來源和計數腳本
				
log = LOAD '/var/log/messages' USING PigStorage(' ') AS (month:chararray, \
  day:int, time:chararray, host:chararray, source:chararray);
sources = GROUP log BY source;
counts = FOREACH sources GENERATE group, COUNT(log);
dump counts;

執行結果如 清單 8 所示。



				
$ pig -x local logsources.pig
...
(init:,1)
(gconfd,12)
(kernel:,505)
(syslogd,2)
(dhclient:,91)
(localhost,1168)
(gpm[2139]:,2)
[gpm[2168]:,2)
(NetworkManager:,292)
(avahi-daemon[3345]:,37)
(avahi-daemon[3362]:,44)
(nm-system-settings:,8)
$

發佈了50 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章