火龙果软件PIG学习记录.docx

上传人:b****5 文档编号:6481314 上传时间:2023-01-06 格式:DOCX 页数:23 大小:27.92KB
下载 相关 举报
火龙果软件PIG学习记录.docx_第1页
第1页 / 共23页
火龙果软件PIG学习记录.docx_第2页
第2页 / 共23页
火龙果软件PIG学习记录.docx_第3页
第3页 / 共23页
火龙果软件PIG学习记录.docx_第4页
第4页 / 共23页
火龙果软件PIG学习记录.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

火龙果软件PIG学习记录.docx

《火龙果软件PIG学习记录.docx》由会员分享,可在线阅读,更多相关《火龙果软件PIG学习记录.docx(23页珍藏版)》请在冰豆网上搜索。

火龙果软件PIG学习记录.docx

火龙果软件PIG学习记录

PIG学习记录

PIG是什么?

Pig提供了一个基于Hadoop的并行地执行数据流处理的引擎。

Pig运行于Hadoop之上,它同时使用到Hadoop分布式文件系统HDFS和Hadoop处理系统MapReduce。

数据类型

基本数据类型:

●int:

整型,4字节

●long:

长整型,8字节

●float:

单精度浮点型,4字节

●double:

双精度浮点型,8字节

●chararray:

字符串

●bytearray:

字节串

复杂数据类型:

●Map:

map是一种chararray和数据元素之间的键值对映射,其中数据元素可以是任意的pig类型,包括复杂类型。

通常使用方括号划定map结构[‘name’#‘bob’,‘age’#55]

●Tuple:

tuple是一个定长的,包含有序pig数据元素的集合,一个tuple相当于SQL中的一行,而tuple字段相当于SQL中的列。

Tuple常量使用圆括号来指示tuple结构,使用逗号划分字段(‘bob’,55)

●Bag:

bag是一种无序的tuple集合。

Bag常量通过花括号进行划分{(‘bob’,55),(‘sally’,52),(‘john’,25)}

NULL:

表示这个值是未知的

模式:

加载数据时显示声明模式:

dividends=load‘NYSE_dividends’as(exchange:

chararray,symbol:

chararray,date:

chararray,dividend:

float);

使用加载函数定义模式:

mdata=load‘mydata’usingHCatLoader();

猜测模式:

calcs=foreachdailygenerate$7/1000,$3*100.0,SUBSTRING($0,0,1),$6-$3;根据运算符两端数据类型和函数参数的数据类型猜测出模式不明的变量的模式

数据类型

语法

举例

int

int

as(a:

int)

long

long

as(a:

long)

float

float

as(a:

float)

double

double

as(a:

double)

chararray

chararray

as(a:

chararray)

bytearray

bytearray

as(a:

bytearray)

map

map[]或者map[type],其中type必须是一个合法的数据类型。

这就声明了map中所有的值都是这个数据类型的

as(a:

map[],b:

map[int])

tuple

tuple()或者tuple(list_of_fields),其中list_of_fields是一组通过逗号分隔的字段声明

as(a:

tuple(),b:

tuple(x:

int,y:

int))

bag

bag{}或者bag{t:

list_of_fields)},其中list_of_fields是一组通过逗号分隔的字段声明。

需要注意的是,bag中的tuple必须要有一个名称,这里指定的名称为t,虽然用户可能永远无法直接访问t这个tuple

(a:

bag{},b:

bag{t:

(x:

int,y:

int)})

类型转换

int

long

float

double

chararray

int

可以

可以

可以

可以

long

可以但会被截断

可以

可以

可以

float

可以但会被截断

可以但会被截断

可以

可以

double

可以但会被截断

可以但会被截断

可以但会被截断

可以

chararray

可以但非数值字符会转换为null

可以但非数值字符会转换为null

可以但非数值字符会转换为null

可以但非数值字符会转换为null

显式转换:

unitended=foreachplayergenerate(int)goal;

隐式转换:

rough=foreachdailygeneratevolume*close;(其中volume为int,close为float,会将volume转换为float)

加载

直接加载文件:

divs=load‘/data/examples/NYSE_dividends’;

通过加载函数加载:

divs=load‘NYSE_dividends’usingHBaseStorage();

默认加载函数:

divs=load‘NYSE_dividends’usingPigStorage(‘,’);

存储

直接存储文件:

storeprocessedinto‘/data/examples/processed’;

通过加载函数加载:

storeprocessedinto‘processed’usingHBaseStorage();

默认加载函数:

storeprocessedinto‘processed’usingPigStorage(‘,’);

输出:

dumpprocessed;

关系操作:

foreach:

接受一组表达式,然后在数据管道中将它们应用到每条记录中

B=foreachAgenerateuser,id;

gain=foreachpricesgenerate$6-$3;

beginning=foreachpricesgenerateopen..close;

与groupby语句结合进行统计

B=groupA1byx;

C=foreachBgenerateSUM(A1.yz);

使用用户自定义函数(UDF)

Upped=foreachdivsgenerateUPPER(symbol)assymbol,dividends;

describe:

显示字段模式

describesym;

filter:

过滤流记录项

startswithcm=filterdivsbysymbolmatches‘CM.*’;

startswithcm=filterdivsbynotsymbolmatches‘CM.*’;

*x==null会返回null

group:

可以把具有相同键值的数据聚合在一起进行分组

grpd=groupdailybystock;

cnt=foreachgrpdgenerategroup,COUNT(daily);

grpd=groupdailyall;--对所有字段进行分组

cnt=foreachgrpdgenerateCOUNT(daily);

orderby:

对用户的数据进行排序,产生一个全排序的输出结果

bydate=orderdailybydate;

bydatensymbol=orderdailybydate,symbol;

使用desc进行降序排序

Byclose=orderdailybyclosedesc,open;--open还是升序排序

distinct:

去除重复值

uniq=distinctdaily;

join:

根据键值联合数据,没有被匹配到的数据会被去掉

jnd=joindailybysymbol,divsbysymbol;

jnd=joindailyby(symbol,date),divsby(symbol,date);

outerjoin:

jnd=joindailyby(symbol,date)leftouter,divsby(symbol,date);

jnd=joindailyby(symbol,date)right,divsby(symbol,date);

jnd=joindailyby(symbol,date)full,divsby(symbol,date);

*自联需要加载同一数据两次

Limit:

从结果中拿出几条数据,会额外产生一个reduce过程

first10=limitdivs10;

Sample:

抽取样本数据,返回一定百分比的行数的数据,通过一个0到1的double指定

some=sampledivs0.1

Parallel:

附加到任一个关系操作符后面控制reduce阶段的并行,可以触发reduce的操作符有group、order、distinct、join、cogroup和cross

bysymbl=groupdailybysymbolparallel10;

*通过setdefault_parallel设置脚本范围有效的并行数

注册UDF:

register‘your_path_to_piggybank/piggybank,jar’;

把函数所在的jar包导入进来

register‘production.py’usingjythonasbballudfs;

注册Python函数,Python脚本必须在用户当前目录下

define:

可用于为用户的javaUDF定义一个别名

definereverseorg.apache.pig.piggybank.evaluation.string.Reverse();

defineconvertcom.acme.financial.CurrencyConverter(‘dollar’,’euro’);

调用静态Java函数

InvokeForInt、InvokeForLong、InvokeForFloat、InvokeForDouble和InvokeForString对应相应的返回值的函数,第1个参数是完整的包名、类名和方法名,第2个参数是一个以空格作为分割符的参数列表,如果这个参数是个数组,[]会跟在这个类型名称后面,如果不需要参数则省略第2个参数

definehexInvokeForString(‘java.lang.Integer.toHexString’,‘int’);

inhex=foreachnonnullgeneratesymbol,hex((int)volume);

definestdevInvokeForDouble(‘com.acme.Stats.stdev’,‘double[]’);

A=load‘input’as(id:

int,dp:

double);

B=groupAbyid;

C=foreachBgenerategroup,stdev(A.dp);

PigLatin的高级应用

高级关系操作

foreach

结合flatten进行分组统计

B=groupAbya,b,c;

C=foreachBgenerate

flatten(group:

:

a)asa,

flatten(group:

:

b)asb,

flatten(group:

:

c)asc,

COUNT(*)asnum;

计算出每一个分组的记录数

内嵌foreach

grpd=groupdailybyexchange;

uniqcnt=foreachgrpg{

sym=daily.symbol;

uniq_sym=distinctsym;

generategroup,COUNT(uniq_sym)

};

*sym=daily.symbol相等于sym=foreachgrpdgeneratedaily.symbol

理论上任何一个PigLatin关系操作符在foreach语句内都是合法的,但是目前只支持distinct、filter、limit和order

该功能可用于从一组记录中找出前k个元素

grpd=groupdivsbysymbol;

top3=foreachgrpd{

sorted=orderdivsbydividendsdesc;

top=limitsorted3;

generategroup,flatten(top);

使用不同的join实现方法

当进行Join时,最后一个表不会放入内存,而是以stream的方式进行处理,所以最好把最大的一个表放置到Join语句的最后。

Pig实现了以下三种定制的Join以进一步优化。

1)ReplicatedJoin(分片-冗余join)

当进行Join的一个表比较大,而其他的表都很小(能够放入内存)时,ReplicatedJoin会非常高效。

ReplicatedJoin会把所有的小表放置在内存当中,然后在Map中读取大表中的数据记录,和内存中存储的小表的数据进行Join,得到Join结果,无需Reduce。

可以在Join时使用Using'replicated'语句来触发ReplicatedJoin,大表放置在最左端,其余小表(可以有多个)放置在右端。

jnd=joindailyby(exchange,symbol),divsby(exchange,symbol)using‘replicated’;

*第2个输入即divs会被加载到内存中

2)SkewedJoin

当进行Join的两个表中,一个表数据记录针对key的分布极其不均衡的时候,简单的使用Hash来分配Reduce端的key时,可能导致某些Reducer上的数据量特别大,降低整个集群的性能。

SkewedJoin可以首先对左边的表的key统计其分布,然后决定Reduce端的key的分布,尽量使得Reduce端的数据分布比较均衡。

可以在Join时使用Using'skewed'语句来触发SkewedJoin,需要进行统计的表(亦即key可能分布不均衡的表)放置在左端。

jnd=joincinfobycity,usersbycityusing‘skewed’;

*join连接的第2个输入将会被进行样本抽样并且会将对应的记录的条数非常大的键分拆到各个reducer中。

第1个输入会对包含这些值的进行冗余复制然后分发到各个reducer中。

3)MergeJoin

当进行Join的两个表都已经是有序的时,可以使用MergeJoin。

Join时,首先对右端的表进行一次采样,对采样的数据创建索引,记录(key,文件名,偏移[offset])。

然后进行map,读取Join左边的表,对于每一条数据记录,根据前一步计算好的索引来查找数据,进行Join。

可以在Join时使用Using'merge'语句来触发MergeJoin,需要创建索引的表放置在右端。

jnd=joindailybysymbol,divsbysymbolusing‘merge’;

*对于原本无序的表而言,由于要先对表进行排序,所以总体效率并不比普通的join高多少

另外,在进行Join之前,首先过滤掉key为Null的数据记录可以减少Join的数据量。

Cogroup:

是group的一般化方式,不是基于一个键收集一个输入的记录,而是基于一个键收集多个输入的记录。

C=cogroupAbyid,Bbyid;

C:

{group:

int,A:

{id:

int,val:

float},B:

{id:

int,val2:

int}}

cogroup可以用于进行一个semi-join的操作

grpd=cogroupdailyby(exchange,symbol),divsby(exchange,symbol);

sjnd=filtergrpdbynotIsEmpty(divs);

final=foreachsjndgenerateflatten(daily);

*semi_join就是当第1个表的键在第2个表中匹配成功时则返回第1个表的记录,以上操作的原理是先使用要进行join的键对两个表进行收集分组并判断出分组中第2个表的数据不为空的分组,最后对第1个表的数据进行解包。

Union:

将两个表合并到一起

C=unionA,B;

Pig中的union并不要求两个表具有相同的模式,如果两个表的字段类型可以通过隐式转换则union之后的表的字段类型将会是转换后的类型,如果无法进行隐式转换1则结果表将会是没有模式的

如果不希望结果表没有模式可以使用onschema

C=uniononschemaA,B;

在读取数据的过程中,如果给定的输入中没有相关的字段,那么值用null填补

Cross:

第1个表的每条记录都会与第2个表的每条记录结合

tonsodata=crossdaily,divsparallel10;

*cross常常会产生大量的数据。

如果给定的输入时n和m条记录,那么cross的输出会产生n*m条记录

cross可以用来进行非等值join(thetajoin)

crossed=crossdaily,divs;

tjnd=filtercrossedbydaily:

:

date

:

date;

*上述操作结果为daily中每条记录都和divs表中所有date更大的记录进行连接

在Pig中集成遗留代码和MapReduce程序

stream:

在流中使用其他程序处理数据

definehd‘highdiv.pl’ship(‘highdiv.pl’);

highdivs=streamdivsthroughhdas(exchange,symbol,date,dividends);

*stream命令中的as语句是非必须的,但是如果没有提供as语句那么结果将没有模式。

所使用的可执行文件在每个map任务或者reduce任务中都会被调用一次,不会对于每条记录都调用一次。

Pig实例化这个可执行文件然后保证数据持续输入是通过标准输入stdin实现的。

同时也会持续检查标准输出stdout,将所得的任意结果传送给数据流中的下一个操作符。

这个可执行文件可以选择是否对每个输入产生一个输出,或者没一定数量的输入产生一个输出,或者只有当所有的输入都被接收后才会产生一个输出

以上操作中定义将使用的可执行文件highdiv.pl的别名为hp并通过ship命令加载highdiv.pl到Hadoop中作为任务的一部分

defineblc‘blacklistchecker.py’cache(‘/data/shared/badurls#badurls’);

goodurls=streamnormalizedthroughblcas(url,pageid);

*cache使用Hadoop的分布式缓存,#号前面的部分是HDFS上的路径,#后面的字符串是可执行文件将读取的文件别名,Hadoop将会把/data/shared/badurls复制到各个task机器的工作目录下啊并命名为badurls

mapreduce:

可以在数据流中直接添加MapReduce任务

goodurls=mapreduce‘blacklistchecker.jar’

storenormalizedinto‘input’

load‘output’as(url,pageid)

‘com.acmeweb.security.BlackListChecker–Iinput–ooutput’;

*mapreduce命令的第1个参数是包含MapReduce任务的JAR文件,store定义了数据如何流入到MapReduce中的,load获取MapReduce中的输出,需要指定模式,第3个参数是可选的,用于传递给Java命令的参数

split:

显式地对数据流进行划分

splitwlogsintoapr03iftimestamp<‘20110404’,

apr02iftimestamp<‘20110403’andtimestamp>‘20110401’,

apr01iftimestamp<‘20110402’andtimestarmp>‘20110331’;

storeapr03into‘20110403’;

storeapr02into‘20110402’;

storeapr01into‘20110401’;

*相当于使用多个filter对数据流进行筛选,实际上pig会将其重写为这样

执行过程控制

set:

用于设置pig执行MapReduce任务的环境变量

Pig提供的set参数

参数

值数据类型

描述

debug

string

设置日志级别是DEBUG。

与在命令行指定-debugDEBUG效果是一样的

default_parallel

integer

为脚本中所有的reduce操作设置一个缺省的并发级别。

job.name

string

为Hadoop任务分配一个名称。

默认情况下这个名称和所执行的脚本的文件名是一样的,或者是一个为交互式进程随机生成的名称

job.priority

string

如果Hadoop集群是使用能力调度器对队列进行优先级控制,那么这个参数可以为Pig任务设置优先级。

提供的值有5个:

very_low、low、normal、high和very_high

PigLatin预处理器

参数传入

参数可以通过命令行传入或者通过一个参数文件传入

yesterday=filterdailybydate==‘$DATE’;

命令行需要传入参数

pig–pDATE=2009-12-17daily.pig

也可以通过-m或者-param_file命令指定参数文件

pig–para_filedaily.paramsdaily.pig

传入文件内的格式是“参数=值”的形式

YEAR=2009-

MONTH=12-

DAY=17

DATE=$YEAR$MONTH$DAY

也可以在脚本内使用%declare和%default标记定义参数

%defaultparallel_factor10;

grp=groupwlogsbypageidparallel$parallel_factor;

通过define语句定义:

definedividend_analysis(daily,year,daily_symbol,daily_open,daily_close)

returnsanalyzed{

divs=load‘NYSE_dividends’as(exchange:

chararray,symbol:

chararray,date:

chararray,dividends:

float);

divsthisyear=filterdivsbydatematches‘$year-.*’;

dailythisyear=filter$dailybydatematches‘$year-.*’;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1