一、介紹
Google的工程師為了方便自己對MapReduce的實現(xiàn)搞了一個叫做Sawzall的工具,Google就放了幾篇論文放在網(wǎng)上,但這玩意在代碼上不開源在設(shè)計思想是開源的,在前面一篇文章中我也提到過Hadoop也推出了類似Sawzall的Pig語言,就是根據(jù)Google放出來的論文山寨的。
Pig是對處理超大型數(shù)據(jù)集的抽象層,在MapReduce中的框架中有map和reduce兩個函數(shù),如果你親手弄一個MapReduce實現(xiàn)從編寫代碼,編譯,部署,放在Hadoop上執(zhí)行這個MapReduce程序還是耗費你一定的時間的,有了Pig這個東東以后不僅僅可以簡化你對MapReduce的開發(fā),而且還可以對不同的數(shù)據(jù)之間進行轉(zhuǎn)換,例如:包含在連接內(nèi)的一些轉(zhuǎn)化在MapReduce中不太容易去實現(xiàn)。
Apache Pig的運行可以純本地的,解壓,敲個“bin/pig -x local”命令直接運行,非常簡單,這就是傳說中的local模式,但是人們往往不是這樣使用,都是將Pig與hdfs/hadoop集群環(huán)境進行對接,我看說白了Apache的Pig最大的作用就是對mapreduce算法(框架)實現(xiàn)了一套shell腳本 ,類似我們通常熟悉的SQL語句,在Pig中稱之為Pig Latin,在這套腳本中我們可以對加載出來的數(shù)據(jù)進行排序、過濾、求和、分組(group by)、關(guān)聯(lián)(Joining),Pig也可以由用戶自定義一些函數(shù)對數(shù)據(jù)集進行操作,也就是傳說中的UDF(user-defined functions)。
經(jīng)過Pig Latin的轉(zhuǎn)換后變成了一道MapReduce的作業(yè),通過MapReduce多個線程,進程或者獨立系統(tǒng)并行執(zhí)行處理的結(jié)果集進行分類和歸納。Map() 和 Reduce() 兩個函數(shù)會并行運行,即使不是在同一的系統(tǒng)的同一時刻也在同時運行一套任務(wù),當(dāng)所有的處理都完成之后,結(jié)果將被排序,格式化,并且保存到一個文件。Pig利用MapReduce將計算分成兩個階段,第一個階段分解成為小塊并且分布到每一個存儲數(shù)據(jù)的節(jié)點上進行執(zhí)行,對計算的壓力進行分散,第二個階段聚合第一個階段執(zhí)行的這些結(jié)果,這樣可以達到非常高的吞吐量,通過不多的代碼和工作量就能夠驅(qū)動上千臺機器并行計算,充分的利用計算機的資源,打消運行中的瓶頸。
所以用Pig可以對TB級別海量的數(shù)據(jù)進行查詢非常輕松,并且這些海量的數(shù)據(jù)都是非結(jié)構(gòu)化的數(shù)據(jù),例如:一堆文件可能是log4j輸出日志存又放于跨越多個計算機的多個磁盤上,用來記錄上千臺在線服務(wù)器的健康狀態(tài)日志,交易日至,IP訪問記錄,應(yīng)用服務(wù)日志等等。我們通常需要統(tǒng)計或者抽取這些記錄,或者查詢異常記錄,對這些記錄形成一些報表,將數(shù)據(jù)轉(zhuǎn)化為有價值的信息,這樣的話查詢會較為復(fù)雜,此時類似MySQL這樣的產(chǎn)品就并非能滿足我們的對速度、執(zhí)行效率上的需求,而用Apache的Pig就可以幫助我們?nèi)崿F(xiàn)這樣的目標(biāo)。
反之,你如果在做實驗的時候,把MySQL中的100行數(shù)據(jù)轉(zhuǎn)換成文本文件放在在pig中進行查詢,會讓你非常失望,為何這短短的100行數(shù)據(jù)查詢的效率極低,呵呵,因為中間有一個生成MapReduce作業(yè)的過程,這是無法避免的開銷,所以小量的數(shù)據(jù)查詢是不適合pig做的,就好比用關(guān)二哥的大刀切青菜一樣。另外,還可以利用Pig的API在Java環(huán)境中調(diào)用,對Apache的Pig以上內(nèi)容請允許我這樣片面的理解,謝謝。
二、基本架構(gòu)
從整體上來看大量的數(shù)據(jù)聚集在HDFS系統(tǒng)上,通過輸入類似SQL的腳本簡化對MapReduce的操作,讓這幾行代碼/腳本去驅(qū)動上千臺機器進行并行計算。
如圖所示:

Pig的實現(xiàn)有5個主要的部分構(gòu)成:
如圖所示:

1.Pig自己實現(xiàn)的一套框架對輸入、輸出的人機交互部分的實現(xiàn),就是Pig Latin 。
2.Zebra是Pig與HDFS/Hadoop的中間層、Zebra是MapReduce作業(yè)編寫的客戶端,Zerbra用結(jié)構(gòu)化的語言實現(xiàn)了對hadoop物理存儲元數(shù)據(jù)的管理也是對Hadoop的數(shù)據(jù)抽象層,在Zebra中有2個核心的類 TableStore(寫)/TableLoad(讀)對Hadoop上的數(shù)據(jù)進行操作。
3.Pig中的Streaming主要分為4個組件: 1. Pig Latin 2. 邏輯層(Logical Layer) 3. 物理層(Physical Layer) 4. Streaming具體實現(xiàn)(Implementation),Streaming會創(chuàng)建一個Map/Reduce作業(yè),并把它發(fā)送給合適的集群,同時監(jiān)視這個作業(yè)的在集群環(huán)境中的整個執(zhí)行過程。
4.MapReduce在每臺機器上進行分布式計算的框架(算法)。
5.HDFS最終存儲數(shù)據(jù)的部分。
三、與Hive對比
請允許我很無聊的把飛機和火車拿來做比較,因為2者根本沒有深入的可比性,雖然兩者都是一種高速的交通工具,但是具體的作用范圍是截然不同的,就像Hive和Pig都是Hadoop中的項目,并且Hive和pig有很多共同點,但Hive還似乎有點數(shù)據(jù)庫的影子,而Pig基本就是一個對MapReduce實現(xiàn)的工具(腳本)。兩者都擁有自己的表達語言,其目的是將MapReduce的實現(xiàn)進行簡化,并且讀寫操作數(shù)據(jù)最終都是存儲在HDFS分布式文件系統(tǒng)上。看起來Pig和Hive有些類似的地方,但也有些不同,來做一個簡單的比較,先來看一張圖:

查看大圖請點擊這里
再讓我說幾句廢話:
Language
在Hive中可以執(zhí)行 插入/刪除 等操作,但是Pig中我沒有發(fā)現(xiàn)有可以 插入 數(shù)據(jù)的方法,請允許我暫且認為這是最大的不同點吧。
Schemas
Hive中至少還有一個“表”的概念,但是Pig中我認為是基本沒有表的概念,所謂的表建立在Pig Latin腳本中,對與Pig更不要提metadata了。
Partitions
Pig中沒有表的概念,所以說到分區(qū)對于Pig來說基本免談,如果跟Hive說“分區(qū)”(Partition)他還是能明白的。
Server
Hive可以依托于Thrift啟動一個服務(wù)器,提供遠程調(diào)用。 找了半天壓根沒有發(fā)現(xiàn)Pig有這樣的功能,如果你有新發(fā)現(xiàn)可以告訴我,就好像有人開發(fā)了一個Hive的REST
Shell
在Pig 你可以執(zhí)行一些個 ls 、cat 這樣很經(jīng)典、很cool的命令,但是在使用Hive的時候我壓根就沒有想過有這樣的需求。
Web Interface
Hive有,Pig無
JDBC/ODBC
Pig無,Hive有
四、使用
1啟動/運行
分為2臺服務(wù)器,一臺作為pig的服務(wù)器,一臺作為hdfs的服務(wù)器。
首先需要在pig的服務(wù)器上進行配置,將pig的配置文件指向hdfs服務(wù)器,修改pig/conf目錄下的
vim /work/pig/conf/pig.properties
添加以下內(nèi)容:
fs.default.name=hdfs://192.168.1.201:9000/ #指向HDFS服務(wù)器
mapred.job.tracker=192.168.1.201:9001 #指向MR job服務(wù)器地址
如果是第一次運行請在Hadoop的HDFS的服務(wù)器上創(chuàng)建root目錄,并且將etc目錄下的passwd文件放在HDFS的root目錄下,請執(zhí)行以下兩條命令。
hadoop fs -mkdir /user/root
hadoop fs -put /etc/passwd /user/root/passwd
創(chuàng)建運行腳本,用vim命令在pig的服務(wù)器上創(chuàng)建javabloger_testscript.pig 文件,內(nèi)容如下:
LoadFile = load 'passwd' using PigStorage(':');
Result = foreach LoadFile generate $0 as id;
dump Result;
運行pig腳本,例如:pig javabloger_testscript.pig,執(zhí)行狀態(tài)如圖所示:

執(zhí)行結(jié)果:

2.java 代碼 運行并且打印運行結(jié)果
import java.io.IOException;
import java.util.Iterator;
import org.apache.pig.PigServer;
import org.apache.pig.data.Tuple;
public class LocalPig {
public static void main(String[] args) {
try {
PigServer pigServer = new PigServer("local");
runIdQuery(pigServer, "passwd");
} catch (Exception e) {
}
}
public static void runIdQuery(PigServer pigServer, String inputFile) throws IOException {
pigServer.registerQuery("LoadFile = load '" + inputFile+ "' using PigStorage(':');");
pigServer.registerQuery("Result = foreach A generate $0 as id;");
Iterator<Tuple> result = pigServer.openIterator("Result ");
while (result.hasNext()) {
Tuple t = result.next();
System.out.println(t);
}
// pigServer.store("B", "output");
}
}
–end–
本文已經(jīng)同步到新浪微博,
點擊這里訪問“J2EE企業(yè)應(yīng)用 顧問/咨詢- H.E.'s Blog”的官方微博。