Hive UDAF运行过程详解.docx

上传人:b****6 文档编号:8217894 上传时间:2023-01-29 格式:DOCX 页数:6 大小:17.15KB
下载 相关 举报
Hive UDAF运行过程详解.docx_第1页
第1页 / 共6页
Hive UDAF运行过程详解.docx_第2页
第2页 / 共6页
Hive UDAF运行过程详解.docx_第3页
第3页 / 共6页
Hive UDAF运行过程详解.docx_第4页
第4页 / 共6页
Hive UDAF运行过程详解.docx_第5页
第5页 / 共6页
点击查看更多>>
下载资源
资源描述

Hive UDAF运行过程详解.docx

《Hive UDAF运行过程详解.docx》由会员分享,可在线阅读,更多相关《Hive UDAF运行过程详解.docx(6页珍藏版)》请在冰豆网上搜索。

Hive UDAF运行过程详解.docx

HiveUDAF运行过程详解

HiveUDAF运行过程详解

介绍hive的用户自定义聚合函数(UDAF)是一个很好的功能,集成了先进的数据处理。

hive有两种UDAF:

简单和通用。

顾名思义,简单的UDAF,写的相当简单的,但因为使用Java反射导致性能损失,而且有些特性不能使用,如可变长度参数列表。

通用UDAF可以使用?

?

所有功能,但是UDAF就写的比较复杂,不直观。

本文只介绍通用UDAF。

UDAF是需要在hive的sql语句和groupby联合使用,hive的groupby对于每个分组,只能返回一条记录,这点和mysql不一样,切记。

UDAF开发概览开发通用UDAF有两个步骤,第一个是编写resolver类,第二个是编写evaluator类。

resolver负责类型检查,操作符重载。

evaluator真正实现UDAF的逻辑。

通常来说,顶层UDAF类继承org.apache.hadoop.hive.ql.udf.GenericUDAFResolver2,里面编写嵌套类evaluator实现UDAF的逻辑。

本文以Hive的内置UDAFsum函数的源代码作为示例讲解。

实现resolverresolver通常继承org.apache.hadoop.hive.ql.udf.GenericUDAFResolver2,但是我们更建议继承AbstractGenericUDAFResolver,隔离将来hive接口的变化。

GenericUDAFResolver和GenericUDAFResolver2接口的区别是,后面的允许evaluator实现可以访问更多的信息,例如DISTINCT限定符,通配符FUNCTION(*)。

publicclassGenericUDAFSumextendsAbstractGenericUDAFResolver{staticfinalLogLOG=LogFactory.getLog(GenericUDAFSum.class.getName());@Override

publicGenericUDAFEvaluatorgetEvaluator(TypeInfo[]parameters)

throwsSemanticException{

//Type-checkinggoeshere!

returnnewGenericUDAFSumLong();

}publicstaticclassGenericUDAFSumLongextendsGenericUDAFEvaluator{

//UDAFlogicgoeshere!

}

}这个就是UDAF的代码骨架,第一行创建LOG对象,用来写入警告和错误到hive的log。

GenericUDAFResolver只需要重写一个方法:

getEvaluator,它根据SQL传入的参数类型,返回正确的evaluator。

这里最主要是实现操作符的重载。

getEvaluator的完整代码如下:

publicGenericUDAFEvaluatorgetEvaluator(TypeInfo[]parameters)

throwsSemanticException{

if(parameters.length!

=1){

thrownewUDFArgumentTypeException(parameters.length-1,

"Exactlyoneargumentisexpected.");

}if(parameters[0].getCategory()!

=ObjectInspector.Category.PRIMITIVE){

thrownewUDFArgumentTypeException(0,

"Onlyprimitivetypeargumentsareacceptedbut"

+parameters[0].getTypeName()+"ispassed.");

}

switch(((PrimitiveTypeInfo)parameters[0]).getPrimitiveCategory()){

caseBYTE:

caseSHORT:

caseINT:

caseLONG:

caseTIMESTAMP:

returnnewGenericUDAFSumLong();

caseFLOAT:

caseDOUBLE:

caseSTRING:

returnnewGenericUDAFSumDouble();

caseBOOLEAN:

default:

thrownewUDFArgumentTypeException(0,

"Onlynumericorstringtypeargumentsareacceptedbut"

+parameters[0].getTypeName()+"ispassed.");

}这里做了类型检查,如果不是原生类型(即符合类型,array,map此类),则抛出异常,还实现了操作符重载,对于整数类型,使用GenericUDAFSumLong实现UDAF的逻辑,对于浮点类型,使用GenericUDAFSumDouble实现UDAF的逻辑。

实现evaluator所有evaluators必须继承抽象类org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator。

子类必须实现它的一些抽象方法,实现UDAF的逻辑。

GenericUDAFEvaluator有一个嵌套类Mode,这个类很重要,它表示了udaf在mapreduce的各个阶段,理解Mode的含义,就可以理解了hive的UDAF的运行流程。

publicstaticenumMode{

/**

*PARTIAL1:

这个是mapreduce的map阶段:

从原始数据到部分数据聚合

*将会调用iterate()和terminatePartial()

*/

PARTIAL1,

/**

*PARTIAL2:

这个是mapreduce的map端的Combiner阶段,负责在map端合并map的数据:

:

从部分数据聚合到部分数据聚合:

*将会调用merge()和terminatePartial()

*/

PARTIAL2,

/**

*FINAL:

mapreduce的reduce阶段:

从部分数据的聚合到完全聚合

*将会调用merge()和terminate()

*/

FINAL,

/**

*COMPLETE:

如果出现了这个阶段,表示mapreduce只有map,没有reduce,所以map端就直接出结果了:

从原始数据直接到完全聚合

*将会调用iterate()和terminate()

*/

COMPLETE

};一般情况下,完整的UDAF逻辑是一个mapreduce过程,如果有mapper和reducer,就会经历PARTIAL1(mapper),FINAL(reducer),如果还有combiner,那就会经历PARTIAL1(mapper),PARTIAL2(combiner),FINAL(reducer)。

而有一些情况下的mapreduce,只有mapper,而没有reducer,所以就会只有COMPLETE阶段,这个阶段直接输入原始数据,出结果。

下面以GenericUDAFSumLong的evaluator实现讲解publicstaticclassGenericUDAFSumLongextendsGenericUDAFEvaluator{privatePrimitiveObjectInspectorinputOI;

privateLongWritableresult;   //这个方法返回了UDAF的返回类型,这里确定了sum自定义函数的返回类型是Long类型

@Override

publicObjectInspectorinit(Modem,ObjectInspector[]parameters)throwsHiveException{

assert(parameters.length==1);

super.init(m,parameters);

result=newLongWritable(0);

inputOI=(PrimitiveObjectInspector)parameters[0];

returnPrimitiveObjectInspectorFactory.writableLongObjectInspector;

}/**存储sum的值的类*/

staticclassSumLongAggimplementsAggregationBuffer{

booleanempty;

longsum;

}//创建新的聚合计算的需要的内存,用来存储mapper,combiner,reducer运算过程中的相加总和。

@Override

publicAggregationBuffergetNewAggregationBuffer()throwsHiveException{

SumLongAggresult=newSumLongAgg();

reset(result);

returnresult;

}

    

//mapreduce支持mapper和reducer的重用,所以为了兼容,也需要做内存的重用。

@Override

publicvoidreset(AggregationBufferagg)throwsHiveException{

SumLongAggmyagg=(SumLongAgg)agg;

myagg.empty=true;

myagg.sum=0;

}privatebooleanwarned=false;

  

//map阶段调用,只要把保存当前和的对象agg,再加上输入的参数,就可以了。

@Override

publicvoiditerate(AggregationBufferagg,Object[]parameters)throwsHiveException{

assert(parameters.length==1);

try{

merge(agg,parameters[0]);

}catch(NumberFormatExceptione){

if(!

warned){

warned=true;

LOG.warn(getClass().getSimpleName()+""

+StringUtils.stringifyException(e));

}

}

}

  //mapper结束要返回的结果,还有combiner结束返回的结果

@Override

publicObjectterminatePartial(AggregationBufferagg)throwsHiveException{

returnterminate(agg);

}

//combiner合并map返回的结果,还有reducer合并mapper或combiner返回的结果。

@Override

publicvoidmerge(AggregationBufferagg,Objectpartial)throwsHiveException{

if(partial!

=null){

SumLongAggmyagg=(SumLongAgg)agg;

myagg.sum+=PrimitiveObjectInspectorUtils.getLong(partial,inputOI);

myagg.empty=false;

}

}

//reducer返回结果,或者是只有mapper,没有reducer时,在mapper端返回结果。

@Override

publicObjectterminate(AggregationBufferagg)throwsHiveException{

SumLongAggmyagg=(SumLongAgg)agg;

if(myagg.empty){

returnnull;

}

result.set(myagg.sum);

returnresult;

}}除了GenericUDAFSumLong,还有重载的GenericUDAFSumDouble,以上代码都在hive的源码:

org.apache.hadoop.hive.ql.udf.generic.GenericUDAFSum。

修改方法注册修改ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java文件,加入编写的UDAF类,并注册名字。

FunctionRegistry类包含了hive的所有内置自定义函数。

想要更好学习hive的UDAF,建议多看看里面的UDAF。

总结本文的目的是为初学者入门学习udaf,所以介绍了udaf的概览,尤其是udaf的运行过程,这对初学者是比较大的槛。

考虑入门,本文简单介绍了sum的UDAF实现,但是如果想要更好理解UDAF的运行过程,建议再看看avgUDAF:

org.apache.hadoop.hive.ql.udf.generic.GenericUDAFAverage。

avgUDAF对hive的运行流程要控制的更加精细,并判断当前运行的Mode做一定的逻辑处理。

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

当前位置:首页 > 小学教育 > 语文

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

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