使用Apache Pig时应该注意/避免的操作或事项

栏目: Apache · 发布时间: 7年前

内容简介:使用Apache Pig时应该注意/避免的操作或事项

转载必须注明出处: http://www.codelast.com/

Apache Pig 是用来处理大规模数据的高级查询语言,配合Hadoop使用,可以在处理海量数据时达到事半功倍的效果,比使用Java,C++等语言编写大规模数据处理程序的难度要小N倍,实现同样的效果的代码量也小N倍。

本文基于以下环境:
pig 0.8.1
文章来源: http://www.codelast.com/
(1) CROSS操作
由于求交叉积可能会导致结果数据量暴增,因此,CROSS操作是一个“昂贵”的操作,可能会耗费Hadoop集群较多的资源,使用的时候需要评估一下数据量的大小。

(2) JOIN操作的顺序
如教程《 Apache Pig中文教程(进阶) 》中的第(6)条所写,当JOIN的各数据集分布严重不均时,你最好考虑一下JOIN的顺序,可以对你的job效率提升有帮助。

(3) FLATTEN一个空的bag将得不会输出任何结果

FLATTEN操作本来会将嵌套展开,生成更多行的结果,但如果被展开的bag是空的,则一行记录也不会生成,这与你想像的可能有点不同:至少也应该生成一行结果吧?不会的,就是一行也不会生成。
在这里我用一个实例来说明。假设有数据文件 1.txt:
[root@localhost ~]$ cat 1.txt
1	2	{(a,b),(c,d)}
77	88	{(p,q),(r,s)}
123	555	{(u,w),(q,t)}

有三列,它们之间是以TAB分隔的。
以下代码:

A = LOAD '1.txt' AS (col1: int, col2: int, col3: bag{t: (first: chararray, second: chararray)});
B = FOREACH A GENERATE col1, col2, FLATTEN(col3);
DUMP B;

得到的结果是显而易见的:

(1,2,a,b)
(1,2,c,d)
(77,88,p,q)
(77,88,r,s)
(123,555,u,w)
(123,555,q,t)

可见记录被解嵌套了。
但是,如果第三列的bag是空的:

[root@localhost ~]$ cat 1.txt
1	2	{}
77	88	{}
123	555	{}

那么,与上面同样的代码将什么也不会输出(你可以自己试验一下)。
这一点需要特别注意,所以一般来说,你在FLATTEN一个bag之前,需要判断一下它是否是空的(IsEmpty),如果你需要在FLATTEN的结果中标记空的那些bag,那么你就需要自己在FLATTEN之前将空的bag替换为自己指定的内容。

(4) SAMPLE的结果数量是不确定的
SAMPLE操作符可以对一个关系(relation)进行取样,得到其一定百分比的数据(例如随机取其中10%的数据),但是,这并不保证对同一个relation进行同样比例的SAMPLE,得到的tuple的数量就是相同的。例如,对一个有千万行的数据集,SAMPLE 0.1的结果,可能第一次会得到100万行,重做一次却得到了101万行(这里只是举一个例子,具体的数字是未知的)。
我的试验结果可以肯定地告诉大家:我拿一个含上亿条记录的数据集SAMPLE 0.1两次的结果相差了4万多条记录(指的是数据条数)。

(5) 输出几个简单数据的job,没必要单独跑,使用UNION整合在一个Pig脚本中即可
假设有几个Pig job,它们输出的都是一行数据(当然,一行可能有多列),那么没必要单独跑几个job再得到所有结果,你可以用UNION把它们整合放在一个Pig脚本中,例如:

A1 = LOAD '1.txt' AS (col: chararray);
A2 = LOAD 'a.txt' AS (col: chararray);
A2 = LOAD 'P.txt' AS (col: chararray);

B1 = GROUP A1 ALL;
C1 = FOREACH B1 GENERATE COUNT(A1);

B2 = GROUP A2 ALL;
C2 = FOREACH B2 GENERATE COUNT(A2);

B3 = GROUP A3 ALL;
C3 = FOREACH B3 GENERATE COUNT(A3);

U = UNION C1, C2, C3;

STORE U INTO 'res';

有人说,为什么不把A1,A2,A3使用通配符一起加载?答:这里我假设了一种非常简单的情况:三个数据文件都只有一列,而实际中,可能三个文件完全有不同的格式,而且后面的处理针对每个job也是不同的(在这里为简单起见才写成相同的),因此,单独加载有时候是必要的。
这样做之后,会输出3个文件,每个文件中有一个数。比跑3个Pig job方便。
文章来源: http://www.codelast.com/
(6) 用ORDER排序时,Pig并不遵守“相同的key的记录会被发送到同一个partition”的惯例
处理海量数据时,我们常常会遇到这样一种情况:某些key的数据远远多于其他key的数据。例如,我们要分析用户的web访问日志,会发现用户访问Google的次数远远多于其他网站的次数。
所以,如果我们要按“访问的网站”这个字段来GROUP或者ORDER的话,就会造成落入某些reducer的数据远远多于其他reducer(GROUP、ORDER都会触发reduce过程)——注意,这里说“某些reducer”,是因为在这个例子中,不仅访问Google是个大户,可能还有其他的网站访问大户。
由于这些reducer需要处理的数据量特别大,也就会导致所需的时间特别长,从而整个job所需的总时间特别长。为了解决这一弊端,Pig使用了一种聪明的方法:先对需要ORDER的数据进行采样,获知其key分布情况,然后根据此分布构造一个可以均衡全体数据的partitioner,从而将数据比较均匀地送到N个reducer上。Pig的这种算法是很有效的,它使得各个reducer之间的执行时间相差不大。
正因为Pig做了这样的工作,所以,前面例子中所说的对Google的访问记录可能会被送到多个reducer中,它们有相同的key,却没有被送到同一reducer中,这没有遵守MapReduce的惯例。如果你的数据处理流程需要遵守此惯例,那么就不能用Pig的ORDER来排序。
同时,正因为Pig在ORDER时需要对输入数据进行采样,所以,ORDER的时候Pig会为你的数据流程添加一个额外的轻量job来完成采样工作——从Pig在控制台输出的信息中,你可以看到一个Feature为“ SAMPLER ”的job,这个job就是采样用的。

(7) 关系操作符(Relational Operator)只能对关系(relation)进行操作,而不能对表达式(expression)进行操作吗?
有人说,从这一句的陈述来看,它根本就是废话——关系操作符当然是操作关系的啊!
不过,答案是:不一定。例如,DISTINCT 是一个关系操作符,但是它却可以对表达式进行操作!
我拿一个例子来说明这个问题。有以下数据文件:

[root@localhost ~]$ cat 1.txt 
1	2	3
2	5	3
2	6	7
8	6	3
1	5	7

有以下Pig代码(没什么计算上的意义,就是为了演示用):

A = LOAD '1.txt' AS (col1: int, col2: int, col3: int);
B = GROUP A BY col3;
C = FOREACH B {
	E = DISTINCT A.col3;
	GENERATE group, COUNT(E);
};
DUMP C;

完全可以成功执行,结果为:

(3,1)
(7,1)
从这段代码能看出什么?首先,A.col3 是一个表达式(expression),而不是一个关系(relation),但是,DISTINCT 这个操作符却应用在了它上面,这说明,关系操作符完全是有可能应用在表达式上的。
某些书/资料上有一种说法是,上面的代码是有语法错误的,你必须用以下的代码来替代:
A = LOAD '1.txt' AS (col1: int, col2: int, col3: int);
B = GROUP A BY col3;
C = FOREACH B {
	D = A.col3;
	E = DISTINCT D;
	GENERATE group, COUNT(E);
};
DUMP C;

这段代码确实没有错误,它先通过 A.col3 这个表达式,生成了一个关系(relation) D,再将 DISTINCT 关系操作符应用于其上,这样就避开了所谓的“关系操作符只能操作关系”的限制。但事实上,我们完全没有必要这样做,正如上面的代码的试验结果,你完全可以直接用 DISTINCT A.col3,并不会出错。
所以说,书本也有坑爹的时候,不可全信。

(8) 嵌套的 FOREACH 中的代码是串行执行的
嵌套的 FOREACH 语句可以完成复杂的操作,例如在嵌套的 FOREACH 中对bag进行 排序 等。FOREACH会被并行执行,但是对嵌套在其中的子语句来说,它们却是串行执行的。

(9) PARALLEL只对强制产生reduce过程的操作符有效
通过PARALLEL,你可以控制Pig程序的并行度(说白了就是控制reducer的数量)。PARALLEL可以附加在任何关系操作符上,但是它只对reduce端的并行度起控制作用,因为MapReduce不允许用户自己控制map端的并行度,它只允许用户控制reduce端的并行度,所以,这就是PARALLEL只对强制产生reduce过程的操作符有效的原因了。
另外,在本地模式(pig -x local)下,PARALLEL是不起任何作用的(被忽略),因为在本地模式下所有操作都是串行执行的。

(未完待续)


以上所述就是小编给大家介绍的《使用Apache Pig时应该注意/避免的操作或事项》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

云攻略

云攻略

马克·贝尼奥夫、卡莱尔·阿德勒 / 徐杰 / 海天出版社 / 2010年8月 / 36.00元

Apple、Google、甲骨文、腾讯 都已投入了云的怀抱, 你还在等什么? 快来加入我们! 最初,Salesforce.com 只是一间小小的租赁公寓 在短短10年内 它已成长为 世界上发展最快、最具创新力的 产业变革领导者 曾经,这是个软件为王的时代。 现在,这是个云计算的新时代。 NO SOFTWARE 抛弃软件的......一起来看看 《云攻略》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具