项目中需要把source为xml的文件通过flume放置到hdfs,然后通过MR导入到vertica中去,我之前做过简单的

尝试,是通过pig的piggybank的xmlloader然后Regex_extract来提取结点属性做的,但问题是我之前只取了一

层结点的属性,没有把不同层次结点关联起来,这有三四层,结构比较复杂,我需要重新整理思路.

这种方式很可能走不通,因为piggybank里面regex_extract的正则和传统的正则还是有些异同的.常常会

因为正则写的不合适经常返回空元组.

我是一个c# guy,又不会用纯java写MR,所以就进一步搜索了google.查找相关资料.

1.把XML先转成avro的形式,然后再使用pig 进行转换,可以减少CPU的利用率和IO的情况,具体可以参见slides:

http://www.slideshare.net/Hadoop_Summit/bose-june26-405pmroom230cv3-24148869

不清楚Avro,所以个人尚未尝试过此种处理方式.

2.使用StreamingXMLLoader,来处理复杂的巨大的xml文件.

可以参见这篇文章How to feed XML to your Pig

http://www.tuicool.com/articles/vEJbUj

The class is in a third party project :Mortar.

这是一个第三方的工程,我也不清楚,所以也放弃了.

3.使用Mahout的相关类.不清楚,未使用过.但搜索出来说mahout中相关的文档格式处理可以做这件事.

4.使用pig的piggybank中xmlloader,但xmlloader用起来虽然简单,但其思路也简单,就是传入标签,然后获取

此标签下的所有原生的XML,这对于此标签下有更多的复杂元素时,进一步处理起来还是很复杂的,如果是

简单的,只有一两层的话,可以使用此法取到标签,然后再使用regex_extract来用正则获取下层的元素.

我在项目中一开始尝试的就是这个.

作为一个C# guy,我没有用java写过有意义的程序,最多就是hello world,所以当我决定使用java来写pig

UDF的时候,

在java项目中导入第三方jar包:

http://blog.csdn.net/justinavril/article/details/2783182

我在浏览器中打开pig 官方文档页面和pig udf manual页面作为参考,最后再从查阅pig自带的示例脚本中得到启发.

整个学习的过程中,我还参照了一本书:programming pig,通过ppurl下载的.然后完成了以下的内容.

我还是通过xmlloader来获取最基本的结点,然后可以通过regex_extract来获取其属性.

然后把它作为字符串传入两个自定义的UDF,每一个udf返回的类型都是databag,然后通过flatten函数扁平化,

作为另外两张表的输入,传入到vertica.

以上是需求的分析,其实使用C# or java 通过 dom和xpath来作还是非常简单的.

java工程中我写了三个类,两个类分别实现了两个UDF,都是返回databag,重写了返回的schema.

第三个类是一个测试驱动,里面有一个main函数来调用写的UDF,测试有没有异常.

java项目开发完毕后,需要编译和打包,以下代码是示例,注意编译的时候也需要把pig...jar加进去.

编译成类并打包:

[hadoop@namenode test]$ ls

GetDataLogs.java GetStepNodes.java

[hadoop@namenode test]$ javac -cp ../pig-0.12.0.jar GetStepNodes.java

[hadoop@namenode test]$ javac -cp ../pig-0.12.0.jar GetDataLogs.java

[hadoop@namenode test]$ ls

GetDataLogs.class GetDataLogs.java GetStepNodes.class GetStepNodes.java

[hadoop@namenode test]$ cd ..

[hadoop@namenode src]$ ls

pig-0.12.0.jar test

[hadoop@namenode src]$ jar -cf test.jar test

[hadoop@namenode src]$ ls

pig-0.12.0.jar test test.jar

以下是pig latin代码示例,仅供参考:

register /home/hadoop/workspace/test/src/test.jar

register /home/hadoop/pig-0.12.0/contrib/piggybank/java/piggybank.jar

xml = load '/FFA/FFA_TEST.xml' using org.apache.pig.piggybank.storage.XMLLoader('CIMProjectResults') as(testrun:chararray);

stepnodes = foreach xml generate flatten(test.GetStepNodes(testrun));

dump stepnodes;

datalognodes = foreach xml generate flatten(test.GetDataLogs(testrun));

dump datalognodes;

JAVA示例代码如下:

package test;

import java.io.IOException;
import java.io.StringReader; import org.apache.pig.EvalFunc;
import org.apache.pig.backend.executionengine.ExecException;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag; import javax.xml.parsers.*; import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import javax.xml.xpath.*; import org.apache.pig.impl.logicalLayer.FrontendException;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.data.DataType; public class GetDataLogs extends EvalFunc<DataBag>{ TupleFactory mTupleFactory = TupleFactory.getInstance();
BagFactory mBagFactory = BagFactory.getInstance(); private DataBag GetDataLogNodes(Tuple input) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException
{
DataBag output = mBagFactory.newDefaultBag();
try {
String xml = input.get(0).toString(); DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml))); XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath(); XPathExpression expr = xpath.compile("CIMProjectResults/Sequence");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result; NodeList stepNodes = nodes.item(0).getChildNodes();
if(stepNodes == null) return null;
for(int i=0;i<stepNodes.getLength();i++)
{
if(stepNodes.item(i).getNodeType()!=Node.ELEMENT_NODE) continue;
NodeList stepchildnodes = stepNodes.item(i).getChildNodes();
NamedNodeMap stepAttrs = stepNodes.item(i).getAttributes();
if(stepAttrs == null) continue;
if(stepchildnodes == null) continue;
String TestResult = "";
String TableName = ""; for(int k=0;k<stepchildnodes.getLength();k++)
{
if(stepchildnodes.item(k).getNodeName()=="DataLog")
{
NamedNodeMap dlattrs = stepchildnodes.item(k).getAttributes();
if(dlattrs==null) continue;
TestResult = dlattrs.getNamedItem("TestResult").getNodeValue()==null?"":dlattrs.getNamedItem("TestResult").getNodeValue();
TableName = dlattrs.getNamedItem("TableName").getNodeValue()==null?"":dlattrs.getNamedItem("TableName").getNodeValue();
break;
}
} for(int k=0;k<stepchildnodes.getLength();k++)
{
Tuple t = null;
NodeList testparmnodes = null;
if(stepchildnodes.item(k).getNodeType() == Node.ELEMENT_NODE)
{
if(stepchildnodes.item(k).getNodeName()=="TestParms")
{
testparmnodes = stepchildnodes.item(k).getChildNodes();
if(testparmnodes==null)
{
////////////////////////
t = mTupleFactory.newTuple(9);
t.set(0,stepAttrs.getNamedItem("StepName").getNodeValue()==null?"":stepAttrs.getNamedItem("StepName").getNodeValue());
t.set(1,stepAttrs.getNamedItem("StepNumber").getNodeValue()==null?"":stepAttrs.getNamedItem("StepNumber").getNodeValue());
t.set(2, TestResult);
t.set(3,TableName);
output.add(t);
continue;
}
for(int l=0; l<testparmnodes.getLength();l++)
{
if(testparmnodes.item(l).getNodeType()!=Node.ELEMENT_NODE) continue;
t = mTupleFactory.newTuple(9);
t.set(0,stepAttrs.getNamedItem("StepName").getNodeValue()==null?"":stepAttrs.getNamedItem("StepName").getNodeValue());
t.set(1,stepAttrs.getNamedItem("StepNumber").getNodeValue()==null?"":stepAttrs.getNamedItem("StepNumber").getNodeValue());
t.set(2, TestResult);
t.set(3,TableName);
NamedNodeMap testparmnnm = testparmnodes.item(l).getAttributes();
if (testparmnnm==null) {output.add(t);continue;}
t.set(4,testparmnnm.getNamedItem("Name").getNodeValue()==null?"":testparmnnm.getNamedItem("Name").getNodeValue());
t.set(5,testparmnnm.getNamedItem("Value").getNodeValue()==null?"":testparmnnm.getNamedItem("Value").getNodeValue());
t.set(6,testparmnnm.getNamedItem("Optional").getNodeValue()==null?"":testparmnnm.getNamedItem("Optional").getNodeValue());
t.set(7,testparmnnm.getNamedItem("Set").getNodeValue()==null?"":testparmnnm.getNamedItem("Set").getNodeValue());
t.set(8,testparmnnm.getNamedItem("Key").getNodeValue()==null?"":testparmnnm.getNamedItem("Key").getNodeValue());
output.add(t);
} //l
}//else if
}//if
}//k
}//i } catch (ExecException e) {
e.printStackTrace();
}
return output;
} public DataBag exec(Tuple input) throws IOException {
if (input == null || input.size() == 0 )
return null;
try{
return GetDataLogNodes(input);
}catch(Exception e){
e.printStackTrace();
return null;
}
} @Override
/**
* This method gives a name to the column.
* @param input - schema of the input data
* @return schema of the input data
*/
public Schema outputSchema(Schema input) { Schema bagSchema = new Schema();
bagSchema.add(new Schema.FieldSchema("StepName", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("StepNumber", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("TestResult", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("TableName", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("Name", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("Value", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("Optional", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("Set", DataType.CHARARRAY));
bagSchema.add(new Schema.FieldSchema("Key", DataType.CHARARRAY)); try{
return new Schema(new Schema.FieldSchema(getSchemaName(this.getClass().getName().toLowerCase(), input),
bagSchema, DataType.BAG));
}catch (FrontendException e){
return null;
}
}
}

现在的pig script 只是load了一个文件,而事实上是有成千上万上文件,pig里面的代码是可以写成参数的,

然后传递参数过去。

log = load '$input' as (schema.....)

lmt =limit log $size;

dump lmt;

当你调用的时候可以使用:pig -parm input =....-parm size=4  mypigfilename.pig

你可以在shell里面使用。

pig 里面一次不是只能处理一个文件,而是可以处理一个或多个目录下面的多个相同数据结构的文件.可以使用通配符,例如

xmlfiles/*.xml

xml in hadoop ETL with pig summary的更多相关文章

  1. hadoop生态圈安装详解(hadoop+zookeeper+hbase+pig+hive)

    -------------------------------------------------------------------* 目录 * I   hadoop分布式安装   * II zoo ...

  2. hadoop家族之pig入门

    昨天成功运行第一个在hadoop集群上面的python版本的wordcount,今天白天继续看网上提供的文档.下午上头给定的回复是把hadoop家族都熟悉一下,那就恭敬不如从命,开始学习pig吧- 这 ...

  3. 大数据时代之hadoop(六):hadoop 生态圈(pig,hive,hbase,ZooKeeper,Sqoop)

    hadoop是有apache基金会所开发的分布式系统基础架构,其主要提供了两方面的功能:分布式存储和分布式计算. 其中分布式存储是分布式计算的基础,在hadoop的实现里面,提供了分布式存储的接口,并 ...

  4. hadoop cdh5的pig隐式转化(int到betyarray)不行了

    cdh3上,pig支持int到chararray的隐式转化,但到cdh5不行. pig code is as follows: %default Cleaned_Log /user/usergroup ...

  5. 大数据Hadoop生态圈:Pig和Hive

    前言 Pig最早是雅虎公司的一个基于Hadoop的并行处理架构,后来Yahoo将Pig捐献给Apache的一个项目,由Apache来负责维护,Pig是一个基于 Hadoop的大规模数据分析平台. Pi ...

  6. Hadoop学习之pig

    首先明确pig是解决什么问题而出现的,pig是为了简化mapreduce编程而设计的,并且有自己的一套脚本语言.其基本由命令和操作符来定义的,如load,store,它的功能很明确,用来大规模处理数据 ...

  7. 吴裕雄--天生自然HADOOP操作实验学习笔记:pig简介

    实验目的 了解pig的该概念和原理 了解pig的思想和用途 了解pig与hadoop的关系 实验原理 1.Pig 相比Java的MapReduce API,Pig为大型数据集的处理提供了更高层次的抽象 ...

  8. Hadoop Pig简介、安装、试用

    相比Java的MapReduce api,Pig为大型数据集的处理提供了更高层次的抽象,与MapReduce相比,Pig提供了更丰富的数据结构,一般都是多值和嵌套的数据结构.Pig还提供了一套更强大的 ...

  9. Welcome to Apache™ Hadoop®!

    What Is Apache Hadoop? Getting Started Download Hadoop Who Uses Hadoop? News 15 October, 2013: relea ...

随机推荐

  1. 从苹果apns的feedback服务器获取推送失败的token

    在开发自己的苹果推送服务时候,要合理的控制ios设备的Token,而这个Token是由苹果服务器Apns产生的,就是每次app问Apns要Token,由苹果服务器产生的Token会记录到Apns里面, ...

  2. 【学习整理】NOIP涉及的数论 [updating]

    扩展欧几里得 求二元一次不定式方程 的一组解. int exgcd(int a,int b,int &x,int &y) { int t; ;y=;return a;} t=exgcd ...

  3. PHP生成图片验证码demo【OOP面向对象版本】

    下面是我今天下午用PHP写的一个生成图片验证码demo,仅供参考. 这个demo总共分为4个文件,具体代码如下: 1.code.html中的代码: <!doctype html> < ...

  4. jquery中的事件与动画

    一:事件 1.鼠标事件 eg:光棒效果 $(function () { $('li').mouseover(function () { //鼠标移过时 $(this).css('background' ...

  5. mysql bin-log和innodb_log的关系

    首先,二进制日志会记录所有与MySQL数据库有关的日志记录,包括InnoDB.MyISAM.Heap(memory除外)等其他存储引擎的日志.而InnoDB存储引擎的重做日志记录有关该引擎本身的事务日 ...

  6. 桂电在linux、Mac OS环境下使用出校器(支持2.14)

    这是guetsec学长在三院科协学长所抓包逆向分析1.81版出校器的基础上,用python写的一款为Mac和linux环境开发的出校器. 最后我做了略微修改,支持暂时最新版本2.14.下面有直接从源码 ...

  7. VS 2013 Preview 自定义 SharePoint 2013 列表 之 两个Bug

    SharePoint 2013 已RTM了,对于程序员来说又要了解新功能了,同时 VS 2013 也将要 RTM了,两者同时应用定会有不新功能,我们先从 自定义 列表开始. SharePoint 20 ...

  8. canvas圆形进度条

    通过定义一个canvas标签, new方法传进ID值,和旋转角度值,即可生成圆形进度条 <!DOCTYPE html> <html lang="en"> & ...

  9. 使用SWFUpload无刷新上传图片

    使用SWFUpload组件无刷新上传图片 在做项目时,需要用到一个图片的无刷新上传,之前听说过SWFUpload,于是想要通过SWFUpload来进行图片的无刷新上传,由于我的项目属于是ASP.NET ...

  10. ABAP--如何在ALV_Grid的函数中定义下拉列表

    最近经常听到网友和用户需求希望你在ALV Grid的函数中加入下来列表,其实SAP已经考虑了大家的需求,用户的需求是可以实现的.我特地将代码奉献给大家,供大家参考和学习. 代码如下: REPORT.* ...