使用 Apache Pig 處理數據
使用 Apache Pig 從大數據集中得到所需的信息html
Hadoop 的普及和其生態系統的不斷壯大並不使人感到意外。Hadoop 不斷進步的一個特殊領域是 Hadoop 應用程序的編寫。雖然編寫 Map 和 Reduce 應用程序並不十分複雜,但這些編程確實須要一些軟件開發經驗。Apache Pig 改變了這種情況,它在 MapReduce 的基礎上建立了更簡單的過程語言抽象,爲 Hadoop 應用程序提供了一種更加接近結構化查詢語言 (SQL) 的接口。所以,您不須要編寫一個單獨的 MapReduce 應用程序,您能夠用 Pig Latin 語言寫一個腳本,在集羣中自動並行處理與分發該腳本。正則表達式
Pig Latin 示例
讓咱們從一個簡單的 Pig 示例開始介紹,並剖析該示例。Hadoop 的一個有趣的用法是,在大型數據集中搜索知足某個給定搜索條件的記錄(在 Linux® 中被稱爲 grep
)。清單 1 顯示了在 Pig 中實現該過程的簡單性。在所顯示的三行代碼中,只有一行是真正的搜索。第一行只是將測試數據集(消息日誌)讀取到表明元組集合的包中。用一個正則表達式來篩選該數據(元組中的唯一條目,表示爲 $0
或 field 1),而後查找字符序列 WARN
。最後,在主機文件系統中將這個包存儲在一個名爲 warnings 的新文件中,這個包如今表明來自消息的包含 WARN
的全部元組。shell
清單 1. 一個簡單的 Pig Latin 腳本
1
2
3
|
messages = LOAD 'messages';
warns = FILTER messages BY $0 MATCHES '.*WARN+.*';
STORE warns INTO 'warnings';
|
如您所見,這個簡單的腳本實現了一個簡單的流,可是,若是直接在傳統的 MapReduce 模型中實現它,則須要增長大量的代碼。這使得學習 Hadoop 並開始使用數據比原始開發容易得多。數據庫
如今讓咱們更深刻地探討 Pig 語言,而後查看該語言的一些功能的其餘示例。apache
Pig Latin 的基礎知識
Pig Latin 是一個相對簡單的語言,它能夠執行語句。一調語句 就是一個操做,它須要輸入一些內容(好比表明一個元組集的包),併發出另外一個包做爲其輸出。一個包 就是一個關係,與表相似,您能夠在關係數據庫中找到它(其中,元組表明行,而且每一個元組都由字段組成)。編程
用 Pig Latin 編寫的腳本每每遵循如下特定格式,從文件系統讀取數據,對數據執行一系列操做(以一種或多種方式轉換它),而後,將由此產生的關係寫回文件系統。您能夠在 清單 1 中看到該模式的最簡單形式(一個轉換)。安全
Pig 擁有大量的數據類型,不只支持包、元組和映射等高級概念,還支持簡單的數據類型,如 int
、long
、float
、double
、chararray
和 bytearray
。若是使用簡單的類型,您會發現,除了稱爲 bincond
的條件運算符(其操做相似於 C ternary
運算符)以外,還有其餘許多算術運算符(好比 add
、subtract
、multiply
、divide
和 module
)。而且,如您所指望的那樣,還有一套完整的比較運算符,包括使用正則表達式的豐富匹配模式。bash
全部 Pig Latin 語句都須要對關係進行操做(並被稱爲關係運算符)。正如您在 清單 1 中看到的,有一個運算符用於從文件系統加載數據和將數據存儲到文件系統中。有一種方式能夠經過迭代關係的行來 FILTER
數據。此功能經常使用於從後續操做再也不須要的關係中刪除數據。另外,若是您須要對關係的列進行迭代,而不是對行進行迭代,您可使用 FOREACH
運算符。FOREACH
容許進行嵌套操做,如 FILTER
和 ORDER
,以便在迭代過程當中轉換數據。網絡
ORDER
運算符提供了基於一個或多個字段對關係進行排序的功能。JOIN
運算符基於公共字段執行兩個或兩個以上的關係的內部或外部聯接。SPLIT
運算符提供了根據用戶定義的表達式將一個關係拆分紅兩個或兩個以上關係的功能。最後,GROUP
運算符根據某個表達式將數據分組成爲一個或多個關係。表 1 提供了 Pig 中的部分關係運算符列表。
表 1. Pig Latin 關係運算符的不完整列表
雖然這不是一個詳盡的 Pig Latin 運算符清單,但該表提供了一套在處理大型數據集時很是有用的操做。您能夠經過 參考資料 瞭解完整的 Pig Latin 語言,由於 Pig 有一套不錯的在線文檔。如今嘗試着手編寫一些 Pig Latin 腳本,以瞭解這些運算符的實際工做狀況。
得到 Pig
在有關 Hadoop 的早期文章中,我採用的方法是將 Hadoop 安裝和配置爲一個軟件包。但 Cloudera 經過用 Linux 將它打包爲一個虛擬設備,使得 Hadoop 更易於使用。雖然它是一個較大的下載,但它已預創建並配置了虛擬機 (VM),其中不只有 Hadoop,還包括了 Apache Hive 和 Pig。所以,利用一個下載和免費提供的 2 型虛擬機管理程序(VirtualBox 或基於內核的虛擬機 [KVM]),您即可以擁有預配置的、已準備就緒的整個 Hadoop 環境。
讓 Hadoop 和 Pig 啓動並運行
下載完您的特定虛擬機文件以後,須要爲您的特定虛擬機管理程序建立一個 VM。在 參考資料 中,您能夠找到該操做的分步指南。
一旦建立了本身的 VM,就能夠經過 VirtualBox 來啓動它,VirtualBox 引導 Linux 內核,並啓動全部必要的 Hadoop 守護進程。完成引導後,從建立一個與 Hadoop 和 Pig 通訊的終端開始相關操做。
您能夠在兩種模式中任選一種來使用 Pig。第一種是 Local(本地)模式,它不須要依賴 Hadoop 或 Hadoop 分佈式文件系統 (HDFS),在該模式中,全部操做都在本地文件系統上下文中的單一 Java 虛擬機 (JVM) 上執行。另外一種模式是 MapReduce 模式,它使用了 Hadoop 文件系統和集羣。
Local 模式的 Pig
對於 Local 模式,只需啓動 Pig 並用 exectype
選項指定 Local 模式便可。這樣作能夠將您帶入 Grunt 外殼,使您可以以交互方式輸入 Pig 語句:
1
2
3
|
$ pig -x local
...
grunt>
|
在這裏,您可以以交互方式編寫 Pig Latin 腳本的代碼,並查看每一個運算符後面的結果。返回 清單 1,並嘗試使用這個腳本(參見 清單 2)。注意,在這種狀況下,不須要將數據存儲到某個文件中,只需將它轉儲爲一組關係。您可能會在修改後的輸出中看到,每一個日誌行(與 FILTER
定義的搜索條件相匹配)自己就是一個關係(以括號 [()
] 爲界)。
清單 2. 在 Local 模式中以交互方式使用 Pig
1
2
3
4
5
6
7
|
grunt> messages = LOAD '/var/log/messages';
grunt> warns = FILTER messages BY $0 MATCHES '.*WARN+.*';
grunt> DUMP warns
...
(Dec 10 03:56:43 localhost NetworkManager: <
WARN
> nm_generic_enable_loopback(): error ...
(Dec 10 06:10:18 localhost NetworkManager: <
WARN
> check_one_route(): (eth0) error ...
grunt>
|
若是您已經指定 STORE
運算符,那麼它會在一個指定名稱的目錄(而不是一個簡單的常規文件)中生成您的數據。
Mapreduce 模式中的 Pig
對於 MapReduce 模式,必須首先確保 Hadoop 正在運行。要作到這一點,最簡單的方法是在 Hadoop 文件系統樹的根上執行文件列表操做,如 清單 3 所示。
清單 3. 測試 Hadoop 可用性
1
2
3
4
5
6
|
$ hadoop dfs -ls /
Found 3 items
drwxrwxrwx - hue supergroup 0 2011-12-08 05:20 /tmp
drwxr-xr-x - hue supergroup 0 2011-12-08 05:20 /user
drwxr-xr-x - mapred supergroup 0 2011-12-08 05:20 /var
$
|
如清單 3 所示,若是 Hadoop 成功運行,此代碼的結果會是一個或多個文件組成的列表。如今,讓咱們來測試 Pig。從啓動 Pig 開始,而後將目錄更改成您的 HDFS 根,以肯定在 HDFS 中是否能夠看到外部所看到的結果(參見 清單 4)。
清單 4. 測試 Pig
1
2
3
4
5
6
7
8
9
10
11
12
|
$ pig
2011-12-10 06:39:44,276 [main] INFO org.apache.pig.Main - Logging error messages to...
2011-12-10 06:39:44,601 [main] INFO org.apache.pig.... Connecting to hadoop file \
system at: hdfs://0.0.0.0:8020
2011-12-10 06:39:44,988 [main] INFO org.apache.pig.... connecting to map-reduce \
job tracker at: 0.0.0.0:8021
grunt> cd hdfs:///
grunt> ls
hdfs://0.0.0.0/tmp <
dir
>
hdfs://0.0.0.0/user <
dir
>
hdfs://0.0.0.0/var <
dir
>
grunt>
|
到目前爲止,一切都很好。您能夠在 Pig 中看到您的 Hadoop 文件系統,因此,如今請嘗試從您的本地主機文件系統將一些數據讀取到 HDFS 中。能夠經過 Pig 將某個文件從本地複製到 HDFS(參見 清單 5)。
清單 5. 得到一些測試數據
1
2
3
4
5
|
grunt> mkdir test
grunt> cd test
grunt> copyFromLocal /etc/passwd passwd
grunt> ls
hdfs://0.0.0.0/test/passwd<
r
1> 1728
|
接下來,在 Hadoop 文件系統中測試數據如今是安全的,您能夠嘗試另外一個腳本。請注意,您能夠在 Pig 內 cat
文件,查看其內容(只是看看它是否存在)。在這個特殊示例中,將肯定在 passwd 文件中爲用戶指定的外殼數量(在 passwd 文件中的最後一列)。
要開始執行該操做,須要從 HDFS 將您的 passwd 文件載入一個 Pig 關係中。在使用 LOAD
運算符以前就要完成該操做,但在這種狀況下,您可能但願將密碼文件的字段解析爲多個獨立的字段。在本例中,咱們指定了 PigStorage
函數,您可使用它來顯示文件的分隔符(本例中,是冒號 [:
] 字符)。您也能夠用 AS
關鍵字指定獨立字段(或架構),包括它們的獨立類型(參見 清單 6)。
清單 6. 將文件讀入一個關係中
1
2
3
4
5
6
7
8
9
|
grunt> passwd = LOAD '/etc/passwd' USING PigStorage(':') AS (user:chararray, \
passwd:chararray, uid:int, gid:int, userinfo:chararray, home:chararray, \
shell:chararray);
grunt> DUMP passwd;
(root,x,0,0,root,/root,/bin/bash)
(bin,x,1,1,bin,/bin,/sbin/nologin)
...
(cloudera,x,500,500,,/home/cloudera,/bin/bash)
grunt>
|
接下來,使用 GROUP
運算符根據元組的外殼將元組分組到該關係中(參見 清單 7)。再次轉儲此關係,這樣作只是爲了說明 GROUP
運算符的結果。注意,在這裏,您須要根據元組正使用的特定外殼(在開始時指定的外殼)對元組進行分組(做爲一個內部包)。
清單 7. 將元組分組爲其外殼的一個函數
1
2
3
4
5
6
|
grunt> grp_shell = GROUP passwd BY shell;
grunt> DUMP grp_shell;
(/bin/bash,{(cloudera,x,500,500,,/home/cloudera,/bin/bash),(root,x,0,0,...), ...})
(/bin/sync,{(sync,x,5,0,sync,/sbin,/bin/sync)})
(/sbin/shutdown,{(shutdown,x,6,0,shutdown,/sbin,/sbin/shutdown)})
grunt>
|
可是,您想要的是在 passwd 文件中指定的獨特外殼的計數。因此,須要使用 FOREACH
運算符來遍歷分組中的每一個元組,COUNT
出現的數量(參見 清單 8)。
清單 8. 利用每一個外殼的計數對結果進行分組
1
2
3
4
5
6
7
8
9
10
|
grunt> counts = FOREACH grp_shell GENERATE group, COUNT(passwd);
grunt> DUMP counts;
...
(/bin/bash,5)
(/bin/sync,1)
(/bin/false,1)
(/bin/halt,1)
(/bin/nologin,27)
(/bin/shutdown,1)
grunt>
|
備註:若是要將該代碼做爲一個腳原本執行,只需將腳本輸入到某個文件中,而後使用 pig myscript.pig
來執行它。
診斷運算符
Pig 支持大量診斷運算符,您能夠用它們來調試 Pig 腳本。正如您在以前的腳本示例中所看到的,DUMP
運算符是無價的,它不只能夠查看數據,還能夠查看數據架構。您還可使用 DESCRIBE
運算符來生成一個關係架構的詳細格式(字段和類型)。
EXPLAIN
運算符更復雜一些,但也頗有用。對於某個給定的關係,您可使用 EXPLAIN
來查看如何將物理運算符分組爲 Map 和 Reduce 任務(也就是說,如何推導出數據)。
表 2 對 Pig Latin 中的診斷運算符及其描述提供了一個列表。
表 2. Pig Latin 診斷運算符
用戶定義的函數
雖然 Pig 在本文探討的範圍內是強大且有用的,可是經過用戶定義的函數 (UDF) 可使它變得更強大。Pig 腳本可使用您爲解析輸入數據、格式化輸出數據甚至運算符等定義的函數。UDF 是用 Java 語言編寫的,容許 Pig 支持自定義處理。UDF 是將 Pig 擴展到您的特定應用程序領域的一種方式。您能夠在 參考資料 中瞭解有關 UDF 開發的更多信息。
Pig 用戶
正如您從這篇短文中能夠看到的,Pig 是一個強大的工具,能夠在 Hadoop 集羣中查詢數據。它是如此強大,Yahoo! 估計,其 Hadoop 工做負載中有 40% 至 60% 由 Pig Latin 腳本產生。在 Yahoo! 的 100,000 個 CPU 中,大約有 50% 的 CPU 仍在運行 Hadoop。
但 Yahoo! 並非利用 Pig 的唯一組織。您在 Twitter 中也會發現 Pig(用於處理日誌和挖掘微博數據);在 AOL 和 MapQuest 上也會發現它(用於分析和批量數據處理);而在 LinkedIn 上,Pig 用於發現您可能認識的人。據報道,Ebay 使用 Pig 來實現搜索優化,而 adyard 的推薦工具系統有大約一半都使用了 Pig。
展望將來
沒有一本書能夠徹底列舉 Pig 背後處理大數據的強大功能。即便對於非開發人員而言,Pig 也可使得執行 Hadoop 集羣上的大數據處理變得很容易。Pig 最初是由 Yahoo! 於 2006 年開發,而且此後不久被遷移到 Apache Software Foundation,使得它在全球範圍獲得普遍應用。進行這種遷移是由於 Yahoo! 研究人員意識到 Pig 能爲非開發人員提供強大的功能。Hadoop 做爲一個基礎架構已經逐漸開始普及,Hadoop 生態系統將會改變大數據的外觀及其日益增加的使用狀況。
相關主題
- Apache 網站 是有關 Pig 的信息來源,包括時事新聞、最新的軟件、如何入門和如何參與。
- Hadoop Demo VM 是目前使 Hadoop 實例運行的最簡單方式。該 VM 中包含了您所需的一切,包括 Hadoop、Hive 和一個 CentOS Linux 操做系統上的 Pig。
- Cloudera Training VM 是一個極佳的 Hadoop 入門方式。它最大限度地減小所需的配置量,讓您能夠輕鬆地開始利用 Hadoop 和 Pig 處理數據集。
- 虛擬設備和 Open Virtualization Format(M. Tim Jones,developerWorks,2009 年 10 月)探討了將虛擬設備用做一種新的軟件交付形式。虛擬設備容許將預配置軟件(帶操做系統)做爲一個 VM 進行分發。
- Pig 有大量的在線資源,包括參考手冊、操做手冊和其餘參考資料。Pig 也有兩本寫得很好的手冊(第 1 部分 和 第 2 部分)、一本 腳本操做手冊 和一本 UDF 指南。
- 擁有由重要的 Web 資產所組成的龐大用戶羣。在 Apache 的 PoweredBy 頁面上了解使用 Pig 的多種 Web 企業。
- 在 developerWorks Linux 專區 中,查找數百篇 指南文章和教程,還有下載、論壇,以及針對 Linux 開發人員和管理員的豐富資源。
- developerWorks 中國網站開源技術專區 提供了有關開源工具和使用開源技術的豐富信息。
- 以最適合您的方式 IBM 產品評估試用版軟件:下載產品試用版,在線試用產品,在雲環境下試用產品,或者在 IBM SOA 人員沙箱 中花費幾個小時來學習如何高效實現面向服務架構。
- 在 developerWorks Linux 專區 尋找爲 Linux 開發人員(包括 Linux 新手入門)準備的更多參考資料,查閱咱們 最受歡迎的文章和教程。
- 在 developerWorks 上查閱全部 Linux 技巧 和 Linux 教程。
- 隨時關注 developerWorks 技術活動和網絡廣播。