Pig系统分析(8)-Pig可扩展性
本文是Pig系统分析系列中的最后一篇了,主要讨论怎样扩展Pig功能。不仅介绍Pig本身提供的UDFs扩展机制,还从架构上探讨Pig扩展可能性。
补充说明:前些天同事发现twitter推动的Pig On Spark项目:Spork,准备研究下。
UDFs
通过UDFs(用户自己定义函数),能够自己定义数据处理方法,扩展Pig功能。实际上,UDFS除了使用之前须要register/define外。和内置函数没什么不同。
主要的EvalFunc
以内置的ABS函数为例:
public class ABS extends EvalFunc<Double>{
/**
* java level API
* @param input expectsa single numeric value
* @return output returns a single numeric value, absolute value of the argument
*/
public Double exec(Tuple input) throws IOException {
if (input == null || input.size() == 0)
return null;
Double d;
try{
d = DataType.toDouble(input.get(0));
} catch (NumberFormatException nfe){
System.err.println("Failed to process input; error -" + nfe.getMessage());
return null;
} catch (Exception e){
throw new IOException("Caught exception processing input row", e);
}
return Math.abs(d);
}
……
public Schema outputSchema(Schema input) ;
public List<FuncSpec> getArgToFuncMapping() throws FrontendException;
}
- 函数都继承EvalFunc接口,泛型參数Double代表返回类型。
- exec方法:输入參数类型为元组,代表一行记录。
- outputSchema方法:用于处理输入和输出Schema
- getArgToFuncMapping:用于支持各种数据类型重载。
聚合函数
EvalFuc方法也能实现聚合函数,这是由于group操作对每一个分组都返回一条记录,每组中包括一个Bag,所以exec方法中迭代处理Bag中记录就可以。
public Long exec(Tuple input) throws IOException {
try {
DataBag bag = (DataBag)input.get(0);
if(bag==null)
return null;
Iterator it = bag.iterator();
long cnt = 0;
while (it.hasNext()){
Tuple t = (Tuple)it.next();
if (t != null && t.size() > 0 && t.get(0) != null )
cnt++;
}
return cnt;
} catch (ExecException ee) {
throw ee;
} catch (Exception e) {
int errCode = 2106;
String msg = "Error while computing count in " + this.getClass().getSimpleName();
throw new ExecException(msg, errCode, PigException.BUG, e);
}
}
Algebraic 和Accumulator 接口
如前所述,具备algebraic性质的聚合函数在Map-Reduce过程中能被Combiner优化。直观来理解,具备algebraic性质的函数处理过程能被分为三部分:initial(初始化,处理部分输入数据)、intermediate(中间过程,处理初始化过程的结果)和final(收尾,处理中间过程的结果)。
比方COUNT函数,初始化过程为count计数操作。中间过程和收尾为sum求和操作。更进一步。假设函数在这三个阶段中都能进行同样的操作,那么函数具备distributive性质。比方SUM函数。
Pig提供了Algebraic 接口:
public interface Algebraic{
/**
* Get the initial function.
* @return A function name of f_init. f_init shouldbe an eval func.
* The return type off_init.exec() has to be Tuple
*/
public String getInitial();
/**
* Get the intermediatefunction.
* @return A function name of f_intermed. f_intermedshould be an eval func.
* The return type off_intermed.exec() has to be Tuple
*/
public String getIntermed();
/**
* Get the final function.
* @return A function name of f_final. f_final shouldbe an eval func parametrized by
* the same datum as the evalfunc implementing this interface.
*/
public String getFinal();
}
当中每一个方法都返回EvalFunc实现类的名称。
继续以COUNT函数为例,COUNT实现了Algebraic接口。针对下面语句:
input= load 'data' as (x, y);
grpd= group input by x;
cnt= foreach grpd generate group, COUNT(input);
storecnt into 'result';
Pig会重写MR运行计划:
Map
load,foreach(group,COUNT.Initial)
Combine
foreach(group,COUNT.Intermediate)
Reduce
foreach(group,COUNT.Final),store
Algebraic 接口通过Combiner优化降低传输数据量,而Accumulator接口则关注的是内存使用量。UDF实现Accumulator接口后,Pig保证全部key相同的数据(通过Shuffle)以增量的形式传递给UDF(默认pig.accumulative.batchsize=20000)。相同。COUNT也实现了Accumulator接口。
/* Accumulator interface implementation */
private long intermediateCount = 0L;
@Override
public void accumulate(Tuple b) throws IOException {
try {
DataBag bag = (DataBag)b.get(0);
Iterator it = bag.iterator();
while (it.hasNext()){
Tuple t = (Tuple)it.next();
if (t != null && t.size() > 0 && t.get(0) != null) {
intermediateCount += 1;
}
}
} catch (ExecException ee) {
throw ee;
} catch (Exception e) {
int errCode = 2106;
String msg = "Error while computing min in " + this.getClass().getSimpleName();
throw new ExecException(msg, errCode, PigException.BUG, e);
}
} @Override
public void cleanup() {
intermediateCount = 0L;
}
@Override
/*
*当前key都被处理完之后被调用
*/
public Long getValue() {
return intermediateCount;
}
前后端数据传递
通过UDFs构造函数传递数据是最简单的方法。然后通过define语句定义UDF实例时指定构造方法參数。但有些情况下。比方数据在执行期才产生,或者数据不能用String格式表达,这时候就得使用UDFContext了。
UDF通过getUDFContext方法获取保存在ThreadLoacl中的UDFContext实例。
UDFContext包括下面信息:
- jconf:Hadoop Configuration。
- clientSysProps:系统属性。
- HashMap<UDFContextKey,Properties> udfConfs:用户自己保存的属性,当中UDFContextKey由UDF类名生成。
UDFs运行流程
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaWRvbnR3YW50b2Jl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
Pig架构可扩展性
Pig哲学之三——Pigs Live Anywhere。
理论上。Pig并不被限定执行在Hadoop框架上,有几个能够參考的实现和提议。
- Pigen。Pig on Tez。https://github.com/achalsoni81/pigeon,架构图例如以下:
- Pig的后端抽象层:https://wiki.apache.org/pig/PigAbstractionLayer。
眼下已经实现了PigLatin执行在Galago上。
參考资料
Pig官网:http://pig.apache.org/
Pig paper at SIGMOD 2008:Building a High Level DataflowSystem on top of MapReduce:The Pig Experience
Programming.Pig:Dataflow.Scripting.with.Hadoop(2011.9).Alan.Gates
Pig系统分析(8)-Pig可扩展性的更多相关文章
- Pig系统分析(7)-Pig有用工具类
Explain Explain是Pig提供的调试工具,使用explain能够输出Pig Lation的运行计划.值得一提的是,explain支持-dot选项.将运行计划以DOT格式输出, (DOT是一 ...
- Pig系统分析(5)-从Logical Plan到Physical Plan
Physical Plan生成过程 优化后的逻辑运行计划被LogToPhyTranslationVisitor处理,生成物理运行计划. 这是一个经典的Vistor设计模式应用场景. 当中,LogToP ...
- Pig系统分析(6)-从Physical Plan到MR Plan再到Hadoop Job
从Physical Plan到Map-Reduce Plan 注:由于我们重点关注的是Pig On Spark针对RDD的运行计划,所以Pig物理运行计划之后的后端參考意义不大,这些部分主要分析流程, ...
- pig 介绍与pig版 hello world
前两天使用pig做ETL,粗浅的看了一下,没有系统地学习,感觉pig还是值得学习的,故又重新看programming pig. 以下是看的第一章的笔记: What is pig? Pig provid ...
- pig简介
Apache Pig是MapReduce的一个抽象.它是一个工具/平台,用于分析较大的数据集,并将它们表示为数据流.Pig通常与 Hadoop 一起使用:我们可以使用Apache Pig在Hadoop ...
- Pig Latin程序设计1
Pig是一个大规模数据分析平台.Pig的基础结构层包括一个产生MapReduce程序的编译器.在编译器中,大规模并行执行依据存在.Pig的语言包括一个叫Pig Latin的文本语言,此语言有如下特性: ...
- Hive集成HBase;安装pig
Hive集成HBase 配置 将hive的lib/中的HBase.jar包用实际安装的Hbase的jar包替换掉 cd /opt/hive/lib/ ls hbase-0.94.2* rm -rf ...
- Hadoop Pig简介、安装、试用
相比Java的MapReduce api,Pig为大型数据集的处理提供了更高层次的抽象,与MapReduce相比,Pig提供了更丰富的数据结构,一般都是多值和嵌套的数据结构.Pig还提供了一套更强大的 ...
- Pig + Ansj 统计中文文本词频
最近特别喜欢用Pig,拥有能满足大部分需求的内置函数(built-in functions),支持自定义函数(user defined functions, UDF),能load 纯文本.avro等格 ...
随机推荐
- java获取桌面路径的方法
FileSystemView fsv = FileSystemView.getFileSystemView(); File com=fsv.getHomeDirectory(); System.out ...
- [shell编程] sh脚本异常:/bin/sh^M:bad interpreter: No such file or directory
转载地址:http://www.cnblogs.com/pipelone/archive/2009/04/17/1437879.html 在Linux中执行.sh脚本,异常/bin/sh^M: bad ...
- Kubernetes ServiceAccount的配置
开始配置Kubernetes集群的时候为了少出问题,都是在apiserver配置中去掉ServiceAccount采用非安全连接的方式,但在后面配置FEK日志的过程中,很多时候绕不开这个安全机制,但因 ...
- es6 中的 模板字符串
Template literals are string literals allowing embedded expressions. You can use multi-line strings ...
- Node.js meitulu图片批量下载爬虫1.02版
以前版本需要先查看网页源码,然后肉眼找到图片数量和子目录,虽说不费事,但多少有点不方便. 于是修改了一下,用cheerio自己去找找到图片数量和子目录,只要修改页面地址就行了.至此社会又前进了一步. ...
- 一起talk C栗子吧(第二十二回:C语言实例--队列一)
各位看官们,大家好,上一回中咱们说的是表达式求值的样例,该样例使用了栈,这一回咱们说的是栈的 兄弟:队列. 闲话休提,言归正转.让我们一起talk C栗子吧. 我们在这里说的队列是一种抽象的数据结构, ...
- Android项目总结
功能: 1.图片载入 ImageLoader 參数配置要合理 cacheMemory 一次性的图片最好不要缓存在内存中 合理控制在内存中的内存大小 ,适当的释放 volley是googl ...
- 【转】线程同步------java synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- 【Java】Java_14 循环结构
循环结构 当型:当P条件成立时(T),反复执行A,直到P为“假”时才停止循环. 直到型:先执行A, 再判断P,若为T,再执行A,如此反复,直到P为F. 1.While循环 while循环的基本格式和流 ...
- DB2日期与时间
摘选自:http://www.cnblogs.com/wanghonghu/archive/2012/05/25/2518604.html 1.db2可以通过SYSIBM.SYSDUMMY1.SYSI ...