Apache Pig中文教程(进阶)go on
2015-03-09 00:00
141 查看
(3)重载(overloading)一个UDF
类似于C++的函数重载,pig中也可以重载UDF,例如一个函数ADD可以对两个int进行操作,也可以对两个double进行操作,那么我们可以为该函数实现getArgToFuncMapping方法,该函数返回一个List<FuncSpec>对象,这个对象中包含了参数的类型信息。具体怎么实现,可以看这个链接(搜索“OverloadingUDFs”定位到所需章节)。
(4)pig运行不起来,提示“org.apache.hadoop.ipc.Client-Retryingconnecttoserver:localhost/127.0.0.1:9000.Alreadytried1time(s)”错误的解决办法
发生这个错误时,请先检查Hadoop的各个进程是否都运行起来了,例如,在我的一次操作中,遇到这个错误时,我发现Hadoopnamenode进程没有启动起来:
应该有两个进程启动起来了:
org.apache.hadoop.hdfs.server.namenode.NameNode
org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode
如果没有,那么你要到Hadoop安装目录下的“logs”目录下,查看NameNode的日志记录文件(视用户不同,日志文件的名字也会有不同),例如,我的NameNone日志文件hadoop--namenode-root-XXX.log的末尾,显示出有如下错误:
ERRORorg.apache.hadoop.hdfs.server.namenode.NameNode:org.apache.hadoop.hdfs.server.common.InconsistentFSStateException:Directory/tmp/hadoop-root/dfs/nameisinaninconsistentstate:storagedirectorydoesnotexistorisnotaccessible.
文章来源:http://www.codelast.com/
我到它提示的地方一看,果然不存在最后一级目录(我是伪分布式运行的Hadoop,不要觉得奇怪),于是手工创建了这个目录,然后停掉Hadoop:
稍候一会儿再重新启动Hadoop:
然后再去看一下NameNode的日志,又发现了新的错误信息:
ERRORorg.apache.hadoop.hdfs.server.namenode.NameNode:java.io.IOException:NameNodeisnotformatted.
这表明NameNode没有被格式化。于是将其格式化:
命令行问你是否要格式化的时候,选择YES即可。格式化完后会提示:
common.Storage:Storagedirectory/tmp/hadoop-root/dfs/namehasbeensuccessfullyformatted.
说明成功了。这个时候,再像前面一样重启Hadoop进程,再去看NameNode的日志文件的最后若干行,应该会发现前面的那些错误提示没了。这个时候,再检查Hadoop各进程是否都成功地启动了,如果是的话,那么这个时候你就可以在Hadoop的伪分布式模式下启动pig:
而不用以本地模式来运行pig了(pig-xlocal)。
总之,配置一个伪分布式的Hadoop来调试pig在某些情况下是很有用的,但是比较麻烦,因为还牵涉到Hadoop的正确配置,但是最好搞定它,以后大有用处啊。
(5)用Pig加载HBase数据时遇到的错误“ERROR2999:Unexpectedinternalerror.couldnotinstantiate'com.twitter.elephantbird.pig.load.HBaseLoader'withargumentsXXX”的原因之一
你也许早就知道了:Pig可以加载HBase数据,从而更方便地进行数据处理。但是在使用HBase的loader的时候,可能会遇到这样那样的问题,我这里就遇到了一例,给大家分析一下原因。
使用org.apache.pig.backend.hadoop.hbase.HBaseStorage()可以加载HBase数据,例如:
其中,table_name是你要加载数据的HBase表名,column_family_name:qualifier_name是表的columnfamily:qualifier(当然,可以有多个columnfamily:qualifier,以空格隔开即可),-loadKeytrue-limit100是加载数据时指定的参数,支持的参数如下:
-loadKey=(true|false)Loadtherowkeyasthefirstcolumn
-gt=minKeyVal
-lt=maxKeyVal
-gte=minKeyVal
-lte=maxKeyVal
-limit=numRowsPerRegionmaxnumberofrowstoretrieveperregion
-delim=chardelimitertousewhenparsingcolumnnames(defaultisspaceorcomma)
-ignoreWhitespace=(true|false)ignorespaceswhenparsingcolumnnames(defaulttrue)
-caching=numRowsnumberofrowstocache(fasterscans,morememory).
-noWAL=(true|false)Setsthewriteaheadtofalseforfasterloading.
Tobeusedwithextremecaution,sincethiscouldresultindataloss
(seehttp://hbase.apache.org/book.html#perf.hbase.client.putwal).
由这些参数的解释,可知我上面的-loadKeytrue使得加载出来的数据的第一列是HBase表的rowkey;-limit100使得从每一个region加载的最大数据行数为100(当你有N个region时,总共加载的数据是不是N*region总数条,我没有试验)。
org.apache.pig.backend.hadoop.hbase.HBaseStorage()包含在Pig的jar包中,所以你不需要REGISTER额外的jar包。
我遇到的问题是:在按上面的代码加载HBase数据之后,在grunt中一回车,马上报错:
ERROR2999:Unexpectedinternalerror.couldnotinstantiate'com.twitter.elephantbird.pig.load.HBaseLoader'withargumentsXXX
Detailsatlogfile:XXX
这个时候,你当然应该去查看logfile,以确定具体问题是什么。
logfile内容较多,在其尾部,有下面的内容:
Causedby:java.lang.NoSuchMethodError:org.apache.hadoop.hbase.HBaseConfiguration.create()Lorg/apache/hadoop/conf/Configuration;
atorg.apache.pig.backend.hadoop.hbase.HBaseStorage.<init>(HBaseStorage.java:185)
文章来源:http://www.codelast.com/
好吧,到了这里,只能去看看pig的源码了。打开HBaseStorage.java文件,找到提示的185行,看到如下代码:
可见它调用了HBase代码中的一个类HBaseConfiguration的create方法。按上面的提示,它是找不到这个方法,于是我们再看看使用的HBase的HBaseConfiguration.java里的代码,找遍全文,都找不到create方法!那么,我们再看看更新一点的版本的HBase的相同文件中是否有这个方法呢?下载0.90.4版本的HBase,果然在HBaseConfiguration.java中找到了create方法:
所以,问题就在这里了:Pig的HBaseloader不能使用某些版本的HBase,升级HBase吧!
另外,就算HBase版本适用了,你也得让Pig知道HBase的参数配置(要不然怎么可以指定一个HBase表名就可以加载其数据了呢),具体你可以看这个链接的说明。
(6)JOIN的优化
如果你对N个关系(relation)的某些字段进行JOIN,也就是所谓的“多路的”(multi-way)JOIN——我不知道用中文这样描述是否正确——在这种情况下,请遵循这样的原则来写JOIN语句:
JOIN用到的key所对应的记录最多的那个关系(relation)应该被排在最后。例如:
在这里,假设C这个relation就是上面所说的那种情况,所以把它排在最后。
文章来源:http://www.codelast.com/
为什么要遵循这样的原则?这是由Pig处理JOIN的方式来决定的。在JOIN的n个关系中,前面的n-1个关系的处理结果会被cache在内存中,然后才会轮到第n个关系,因此,把最占内存的放在最后,有时候是能起到优化作用的。
(7)错误“Backenderror:org.apache.pig.data.BinSedesTuplecannotbecasttoorg.apache.pig.data.DataBag”的原因
如果你正在使用Pig0.8,那么要注意了:出现这个错误,可能是Pig的bug导致的,详见这个链接。
说得简单点就是:此bug会导致无法解引用一个tuple中的bag。通常我们取一个tuple中的bag,是为了FLATTEN它,将记录展开,但是此bug使得你根本连tuple中的bag都输出不了。
此bug并不会影响你的Pig脚本语法解析,也就是说,你的Pig脚本只要写对了,就能运行起来,但是它执行到后面会报错。
(8)如何加载LZO压缩的纯文本数据
如果你的数据是纯文本经由LZO压缩而成,那么你可以用elephant-bird的com.twitter.elephantbird.pig.store.LzoPigStorage来加载它:
注意,这里没有写REGISTERjar包的命令,你需要自己补上。
(9)如何用Pig设置map端的并行度(map数)
从这个链接中的第(9)条,我们知道,无法通过PARALLEL来设置Pigjobmap端的并行度,但是,有没有什么办法可以间接实现这一点呢?
在Java编写的MapReduce程序中,你可以像这个链接中的第(25)点所说的一样,通过FileInputFormat.setMinInputSplitSize()来间接更改map的数量,其实它就与设置mapred.min.split.size参数值的效果是一样的。
在Pig中,我们是可以通过set命令来设置job参数的,所以,我们如果在Pig脚本的开头写上:
将使得对map来说,小于2G的文件将被作为一个split输入,从而一个小于2G的文件将只有一个map。假设我们的Pigjob是一个纯map的job,那么,map数的减少将使得输出文件的数量减少,在某些情况下,这种功能还是很有用的。
注意:上面的命令中,set的参数的单位是字节,所以2G=2*1024*1024*1024=2147483648。
(10)Pig调用现存的静态Java方法
不是每个人都会开发UDF,或者每个人都愿意去写一个UDF来完成一件极其简单的操作的,例如,把一个编码过的URL解码,如果我只想临时用一下这个功能,那么我还要去写一个UDF,累不累啊?
我们知道,java.net.URLDecoder.decode这个静态方法已经实现了URL解码功能:
staticStringdecode(Strings,Stringenc)
使用指定的编码机制对application/x-www-form-urlencoded字符串解码
那么,如何在Pig中使用这个现成的静态方法呢?为了展示这个使用过程,我造了一个数据文件:
就一行,这个URL解码之后应该是:http://zh.wikipedia.org/wiki/搜索引擎因为里面含中文,所以被编码了。
处理此文件的Pig脚本url.pig如下:
文章来源:http://www.codelast.com/
用pig-xlocalurl.pig执行这个脚本,完成后我们查看输出目录下的part-m-00000文件内容,可见它确实被解码成了正确的字符串。
这样,我们就利用了现存的静态Java方法来偷了个懒,很方便。
需要注意的是:只能调用静态方法,并且此调用比同样的UDF实现速度要慢,这是因为调用器没有使用Accumulator或Algebraic接口。根据这位兄台的测试,百万条的记录规模下,调用Java静态方法比UDF大约要慢一倍。至于这样的cost能不能接受,就看你自己的判断了。
类似于C++的函数重载,pig中也可以重载UDF,例如一个函数ADD可以对两个int进行操作,也可以对两个double进行操作,那么我们可以为该函数实现getArgToFuncMapping方法,该函数返回一个List<FuncSpec>对象,这个对象中包含了参数的类型信息。具体怎么实现,可以看
(4)pig运行不起来,提示“org.apache.hadoop.ipc.Client-Retryingconnecttoserver:localhost/127.0.0.1:9000.Alreadytried1time(s)”错误的解决办法
发生这个错误时,请先检查Hadoop的各个进程是否都运行起来了,例如,在我的一次操作中,遇到这个错误时,我发现Hadoopnamenode进程没有启动起来:
1 |
org.apache.hadoop.hdfs.server.namenode.NameNode
org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode
如果没有,那么你要到Hadoop安装目录下的“logs”目录下,查看NameNode的日志记录文件(视用户不同,日志文件的名字也会有不同),例如,我的NameNone日志文件hadoop--namenode-root-XXX.log的末尾,显示出有如下错误:
ERRORorg.apache.hadoop.hdfs.server.namenode.NameNode:org.apache.hadoop.hdfs.server.common.InconsistentFSStateException:Directory/tmp/hadoop-root/dfs/nameisinaninconsistentstate:storagedirectorydoesnotexistorisnotaccessible.
文章来源:
我到它提示的地方一看,果然不存在最后一级目录(我是伪分布式运行的Hadoop,不要觉得奇怪),于是手工创建了这个目录,然后停掉Hadoop:
1 |
1 |
ERRORorg.apache.hadoop.hdfs.server.namenode.NameNode:java.io.IOException:NameNodeisnotformatted.
这表明NameNode没有被格式化。于是将其格式化:
1 |
common.Storage:Storagedirectory/tmp/hadoop-root/dfs/namehasbeensuccessfullyformatted.
说明成功了。这个时候,再像前面一样重启Hadoop进程,再去看NameNode的日志文件的最后若干行,应该会发现前面的那些错误提示没了。这个时候,再检查Hadoop各进程是否都成功地启动了,如果是的话,那么这个时候你就可以在Hadoop的伪分布式模式下启动pig:
1 |
总之,配置一个伪分布式的Hadoop来调试pig在某些情况下是很有用的,但是比较麻烦,因为还牵涉到Hadoop的正确配置,但是最好搞定它,以后大有用处啊。
(5)用Pig加载HBase数据时遇到的错误“ERROR2999:Unexpectedinternalerror.couldnotinstantiate'com.twitter.elephantbird.pig.load.HBaseLoader'withargumentsXXX”的原因之一
你也许早就知道了:Pig可以加载HBase数据,从而更方便地进行数据处理。但是在使用HBase的loader的时候,可能会遇到这样那样的问题,我这里就遇到了一例,给大家分析一下原因。
使用org.apache.pig.backend.hadoop.hbase.HBaseStorage()可以加载HBase数据,例如:
1 |
-loadKey=(true|false)Loadtherowkeyasthefirstcolumn
-gt=minKeyVal
-lt=maxKeyVal
-gte=minKeyVal
-lte=maxKeyVal
-limit=numRowsPerRegionmaxnumberofrowstoretrieveperregion
-delim=chardelimitertousewhenparsingcolumnnames(defaultisspaceorcomma)
-ignoreWhitespace=(true|false)ignorespaceswhenparsingcolumnnames(defaulttrue)
-caching=numRowsnumberofrowstocache(fasterscans,morememory).
-noWAL=(true|false)Setsthewriteaheadtofalseforfasterloading.
Tobeusedwithextremecaution,sincethiscouldresultindataloss
(see
由这些参数的解释,可知我上面的-loadKeytrue使得加载出来的数据的第一列是HBase表的rowkey;-limit100使得从每一个region加载的最大数据行数为100(当你有N个region时,总共加载的数据是不是N*region总数条,我没有试验)。
org.apache.pig.backend.hadoop.hbase.HBaseStorage()包含在Pig的jar包中,所以你不需要REGISTER额外的jar包。
我遇到的问题是:在按上面的代码加载HBase数据之后,在grunt中一回车,马上报错:
ERROR2999:Unexpectedinternalerror.couldnotinstantiate'com.twitter.elephantbird.pig.load.HBaseLoader'withargumentsXXX
Detailsatlogfile:XXX
这个时候,你当然应该去查看logfile,以确定具体问题是什么。
logfile内容较多,在其尾部,有下面的内容:
Causedby:java.lang.NoSuchMethodError:org.apache.hadoop.hbase.HBaseConfiguration.create()Lorg/apache/hadoop/conf/Configuration;
atorg.apache.pig.backend.hadoop.hbase.HBaseStorage.<init>(HBaseStorage.java:185)
文章来源:
好吧,到了这里,只能去看看pig的源码了。打开HBaseStorage.java文件,找到提示的185行,看到如下代码:
1 |
1 2 3 4 5 6 7 8 |
另外,就算HBase版本适用了,你也得让Pig知道HBase的参数配置(要不然怎么可以指定一个HBase表名就可以加载其数据了呢),具体你可以看
(6)JOIN的优化
如果你对N个关系(relation)的某些字段进行JOIN,也就是所谓的“多路的”(multi-way)JOIN——我不知道用中文这样描述是否正确——在这种情况下,请遵循这样的原则来写JOIN语句:
JOIN用到的key所对应的记录最多的那个关系(relation)应该被排在最后。例如:
1 |
文章来源:
为什么要遵循这样的原则?这是由Pig处理JOIN的方式来决定的。在JOIN的n个关系中,前面的n-1个关系的处理结果会被cache在内存中,然后才会轮到第n个关系,因此,把最占内存的放在最后,有时候是能起到优化作用的。
(7)错误“Backenderror:org.apache.pig.data.BinSedesTuplecannotbecasttoorg.apache.pig.data.DataBag”的原因
如果你正在使用Pig0.8,那么要注意了:出现这个错误,可能是Pig的bug导致的,详见
说得简单点就是:此bug会导致无法解引用一个tuple中的bag。通常我们取一个tuple中的bag,是为了FLATTEN它,将记录展开,但是此bug使得你根本连tuple中的bag都输出不了。
此bug并不会影响你的Pig脚本语法解析,也就是说,你的Pig脚本只要写对了,就能运行起来,但是它执行到后面会报错。
(8)如何加载LZO压缩的纯文本数据
如果你的数据是纯文本经由LZO压缩而成,那么你可以用elephant-bird的com.twitter.elephantbird.pig.store.LzoPigStorage来加载它:
1 |
(9)如何用Pig设置map端的并行度(map数)
从
在Java编写的MapReduce程序中,你可以像
在Pig中,我们是可以通过set命令来设置job参数的,所以,我们如果在Pig脚本的开头写上:
1 |
注意:上面的命令中,set的参数的单位是字节,所以2G=2*1024*1024*1024=2147483648。
(10)Pig调用现存的静态Java方法
不是每个人都会开发UDF,或者每个人都愿意去写一个UDF来完成一件极其简单的操作的,例如,把一个编码过的URL解码,如果我只想临时用一下这个功能,那么我还要去写一个UDF,累不累啊?
我们知道,java.net.URLDecoder.decode这个静态方法已经实现了URL解码功能:
staticStringdecode(Strings,Stringenc)
使用指定的编码机制对application/x-www-form-urlencoded字符串解码
那么,如何在Pig中使用这个现成的静态方法呢?为了展示这个使用过程,我造了一个数据文件:
1 2 3 |
处理此文件的Pig脚本url.pig如下:
1 2 3 4 |
用pig-xlocalurl.pig执行这个脚本,完成后我们查看输出目录下的part-m-00000文件内容,可见它确实被解码成了正确的字符串。
这样,我们就利用了现存的静态Java方法来偷了个懒,很方便。
需要注意的是:只能调用静态方法,并且此调用比同样的UDF实现速度要慢,这是因为调用器没有使用Accumulator或Algebraic接口。根据
相关文章推荐
- Apache Pig中文教程(进阶)
- Apache Pig中文教程(进阶)
- Apache Pig中文教程(进阶)
- [原创]Apache Pig中文教程(进阶)
- 1、【绝对给力】Android开发免豆资料(教程+工具+源码)下载地址汇总
- DELL R410/R610/R710 – DRAC远程控制卡使用教程
- BIOS设置 翻译中文图文教程(二)
- [置顶] MFC中调用WPF教程
- 干货!总结19个提升iOS开发技术的必看教程!
- 原 ubuntu14.04英文环境下安装中文输入法
- 简明 Python 教程 第1章 介绍 简介
- Apache Pig中文教程集合
- FW:Android&nbsp;中文视频高清教程(共8…
- BIOS设置 翻译中文图文教程(一)
- Apache Pig 中文教程集合 (转)
- ReportStudio进阶教程(三十三) - 地图开发(七)在地图文件中设置中文
- China security group 一些渗透教程 (老教程了)
- Apache Pig中文教程集合
- [图文]Freenas&nbsp;8.0&nbsp;中文安装教程