標籤:
1.pig與hive的區別
pig和hive比較類似的,都是類sql的語言,底層都是依賴於hadoop
走的mapreduce任務。
pig和hive的區別就是,想要實現一個商務邏輯的話,使用pig需要一步一步操作
而使用hive的話一條SQL就可以搞定。
如果想在很短時間內擷取一個比較複雜的商務邏輯處理結果的話,建議使用pig。
如果需要定時執行的一些任務,建議使用hive。
2:pig和mapreduce對比
pig優點:針對一些基本的處理邏輯,已經做好了封裝,直接使用對應的命令即可。
但是使用mapreduce代碼的話就需要我們自己實現了,並且使用pig還不需要
考慮代碼的最佳化。
使用mapreduce的話會出現資料扭曲的問題,但是使用pig可以避免這個問題。
3:pig的應用情境
最主要的就是資料清洗
4:pig的使用方式
1:在pig(grunt)命令列下執行命令
2:在shell命令下執行
bin/pig -e "A = load ‘a.txt‘ as (id:int,name:chararray);dump A;"
3:使用指令碼來執行
vi my.pig
-- 單行注釋
/*
多行注釋
*/
A = load ‘a.txt‘ as (id:int,name:chararray);
dump A;
執行命令
bin/pig my.pig
5:pig裡面的資料類型
基礎資料型別 (Elementary Data Type)
int、long、float、double、chararray、bytearray、boolean、datetime、biginteger、bigdecimal
注意:chararray,表示字串類型
複合資料型別
tuple、bag、map
注意:
tupe (1,2,3)
bag {(1,2,3),(1,2,3),(1,2,3)}
map [key#value]
6:pig中的一些命令
load:載入資料
A = load ‘a.txt‘ as (id:int,name:chararray)
注意:as 後面指定的檔案資料結構資訊,這個表示會在目前的目錄下找a.txt檔案,
根據(id:int,name:chararray)對檔案中的資料進行解析。這樣需要確保檔案中
這兩列資料中間是使用定位字元分割的。
如果載入的資料中多個列之間不是使用定位字元分割的,那麼在載入資料的時候
就需要執行指定分割符了,例子中是使用逗號進行分割的。
例子:A = load ‘a.txt‘ using PigStorage(",") as (id:int,name:chararray);
A 和 = 之間必須有空格。建議命令之間都加上空格,這樣看起來簡潔,也不容易出錯。
describe:類似於sql中的查看錶結構
例子:describe A;
group : 分組,類似於sql中的groupby
例子:B = group A by id;
foreach:對結果集中的資料進行迭代處理
例子:C = foreach A generate id ,name;
或者也可以使用$0類似的命令來擷取結果集中的資料
C = foreach A generate $0 ,$1;
filter:過濾
例子:D = filter A by id ==‘zs‘;
常用的運算式: ==
!=
>=
<=
>
<
join:類似於sql中的錶鏈接
內連結:
C = join A by id,B by id;
外串連
左外串連:C = join A by id left outer,B by id;
在查詢資料的時候,以左側資料為基準,只返回左側有的資料
右外串連:C = join A by id right outer,B by id;
在查詢資料的時候,以右側資料為基準,只返回右側有的資料。
全外串連:C = join A by id full outer,B by id;
在查詢資料的時候,兩側資料都可以返回。
7:pig的命令
limit:類似於sql中的limit,可以擷取資料集中的一部分資料
例子:B = limit A 10;(取前10條資料)
此種方式pig仍會讀取所有資料,只是在返回的時候返回指定條數的資料
order by:排序,類似於sql中的order by
例子:B = order A by id;
預設是正序,想到倒序的話需要在指定欄位後面添加desc;
order by後面可以指定多個分組欄位。
order A by id desc, name desc (對A中的資料進行排序,先根據ID進行倒序排列,如果ID相等,那麼使用name欄位進行倒序排序。)
SPLIT:根據條件對資料集進行切分
例子:split A into x1 if x>10 ,x2 if x==20 ,x3 if (x>1 and x<10);
union:類似於sql中的union all
例子:C = union A, B;
一般情況下使用union操作的兩個臨時變數的資料結構都一樣,
如果不一樣,可以分下面兩種情況
1:A 中id欄位是float類型的,B中的id欄位是double類型的,這樣的話float可以轉換成double,所以使用union之後產生的臨時變數C中id就是double類型的。
2:A 中id欄位是float類型的,B中的id欄位是chararray類型的,這樣的話兩種資料類型不能想換轉換,所以執行會報錯。
8:pig命令的注意事項
1:所有命令都是以;結尾
2:Pig對命令的大小寫沒有規定,可以使用大寫,也可以小寫,但是,針對pig中的函數就必須使用大寫,因為這些函數在pig中定義的時候就是大寫。
針對PIG處理過程中的臨時變數的名稱,大小寫也是有區分的。
3:在pig中執行的命令其實並不會真正的執行,只有當執行dump或者store命令的時候才會真正指定之前定義的命令。
4:如果某一條命令執行失敗了,那麼只需要修改這條命令,重新執行即可。
9:pig命令列的擴充
fs:可以在pig中執行hdfs中的命令
sh:可以在pig中執行shell命令(在0.8版本之後才有)
clear:清屏
exec:在pig命令列下執行pig指令碼 例子:pig my.pig
history:查看在pig命令列下執行的命令記錄
quit:退出pig命令列
10:pig中的內建函數
avg:求平均數
例子:B = group A by id;
C = foreacg B generate group,AVG(score);
SUM:求和
MAX:求最大值
MIN:求最小值
上面這幾個函數使用方法一樣。
注意:函數名稱必須要大寫。
COUNT():求總數。
1:先分組,再求和。和上面的用法一致。
2:執行類似於select count(*) from table操作。
這樣的話也需要對table中的分組,因為是要求所有的資料總數,所以可以把所有資料分到一個組裡面,
使用B = group A all;(all相當於是一個關鍵字)
再使用C = foreach B generate COUNT(A);
10:pig中自訂函數
使用java代碼自訂函數,需要建立一個類,整合evalFunc類,實現為實現的exec函數,在這裡面就可以對資料進行處理。
先添加maven依賴
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0</version>
</dependency>
package pig;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class UPPER extends EvalFunc<String> {
@Override
public String exec(Tuple input) throws IOException {
if(input==null || input.size()==0 || input.get(0)==null){
return null;
}
try {
String str = (String)input.get(0);
return str.toUpperCase();
} catch (Exception e) {
throw new IOException("轉換大寫失敗 ", e);
}
}
}
代碼實現完之後就需要打包了。
在這打包的話不需要打依賴,直接在eclipse中右鍵export匯出為一個jar即可。
在把這個jar放到pig所在的伺服器上,建議放在pig的根目錄下面。
後面想使用這個函數的時候,需要先把這個jar在pig中註冊一下
register myudf.jar
下面就可以使用前面定義的函數了。
例子:
-- vi myscript.pig
REGISTER myudfs.jar;
A = LOAD ‘a.txt‘ AS (name: chararray, age: int);
B = FOREACH A GENERATE pig.UPPER(name);
DUMP B;
pig -x local myscript.pig
11:實戰一(wlan上網Tlog)
1:先把資料上傳到伺服器上
2:在pig中載入這些資料
A = LOAD ‘HTTP_20130313143750.dat‘ AS (reportTime:long, msisdn:chararray, apmac:chararray, acmac:chararray, host:chararray, siteType:chararray, upPackNum:long, downPackNum:long, upPayLoad:long, downPayLoad:long, httpStatus:chararray);
3:截取需要的資料
B = FOREACH A GENERATE msisdn, upPackNum, downPackNum, upPayLoad, downPayLoad;
4:對資料進行分組
C = GROUP B BY msisdn;
5:對上行,下行資料進行統計
D = FOREACH C GENERATE group, SUM(B.upPackNum), SUM(B.downPackNum), SUM(B.upPayLoad), SUM(B.downPayLoad);
6:儲存清洗的結果
STORE D INTO ‘wlan_result‘;
12:實戰二(tomcat訪問Tlog)
統計PV和UV
pv:其實就是統計檔案中資料的總條數
UV:其實就是統計檔案中獨立ip出現的次數
1:把資料上傳到伺服器
2:使用pig載入資料
A = load ‘access_2015_03_30.log‘ USING PigStorage(‘ ‘) as (ip:chararray,one:chararray,two:chararray,time:chararray,timezone:chararray,method:chararray,url:chararray,http:chararray,statu:long,data:long);
注意:這個記錄檔中資料列之間是使用空格隔開的,所以在使用load的時候需要指定分隔字元
3:截取需要的資料
B = foreach A generate ip,url;
4:統計PV
1)對B中的資料進行分組,都分到一組,使用all關鍵字
C = group B all;
2)在使用count函數求和
PV = foreach C generate COUNT(B);
5:統計UV
1)對B中的資料進行分組,使用ip作為分組欄位,這樣可以保證分組之後這個分組欄位的值是不重複的。
C = group B by ip;
2)對分組之後的C中的資料進行處理,由於只需要統計獨立IP,所以只需要擷取分組欄位即可
D = foreach C generate group;
3)對D中的資料再使用all關鍵字分組,分到一個all組裡面
E = group D all;
4)使用count函數統計獨立IP的總數
UV = foreach E generate COUNT(D);
6:把pv和uv整合到一塊
PV_UV = join PV by ‘1‘,UV by ‘1‘;
7:還需要在PV和UV的資料裡面加上時間欄位
END = foreach PV_UV generate ‘2013-05-30‘,$0,$1;
8:把清洗的資料結果儲存起來
store END into ‘pv_uv‘;
13:pig擴充
設定pig中mr任務的名稱
set job.name ‘my-job-name‘;
建議在使用pig指令碼的時候,在每個pig指令碼的第一行指定上面參數,設定不同的任務名稱。
大資料之pig 命令