Hive UDAF开发--我的补充理解

总结

hive的比较难的部分应该就是GenericUDAF,看了两天终于看明白了,有些点是我本身遇到卡住的点,记录下来但愿对你们有所帮助。html

一开始看的是《Hive 编程指南》中关于GenericUDAF的章节,例子有点难了。讲的是group_concat的实现。查了资料后以为网上写的博客很是好,例子比较简单,更可以明白到底在说什么。java

必定要结合MapReduce的过程来看,才会想明白。web

不要偷懒,要将文章中的代码下载下来,具体查看他所继承的类,才能更快速理解内容。sql

参看

Hive UDAF开发详解
这一篇是最值得参考的文章,这里使用是统计字数的例子,比较简洁。编程

关于ObjectInspector

想要理解GenericUDAF必定要理解ObjectInspector,这是贯彻在其中的一个概念。这里也说了一篇博文,必定要参考。Hive中ObjectInspector的做用
ObjectInspector在我看来是什么?其实就是类型检查和经过这个类能获得值,而且帮助它序列化和反序列化,达到数据流转无障碍的目的。svg

这里写图片描述

上图这些过程之间流转都是经过ObjectInspector达到数据流转的, 要知道这些过程当中不乏有着跨节点的操做。函数

序列化和反序列化

Model

这是必定要理解的,Model是什么? 其实Model就是决定了在Map阶段和Reduce阶段 在涉及到对列进行UDF函数计算的时候,会调用UDF类中的哪些方法,都是由Model值决定的。并非全部的方法都会调用,只会调用有限的几个。再由上面的提到的ObjectInspector进行数据的流转。lua

public static enum Mode {
    /** * 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
  };

这个类就是用来类型检查的。spa

public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters)

这是我很是想说的类,init()他会根据model值的不一样来决定输入的类型和输出的类型,很是的灵活。而且注意,init()的调用不是单次的,是屡次的。.net

// 肯定各个阶段输入输出参数的数据格式ObjectInspectors
public  ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException;

注意这里的迭代,当map阶段从表中读取一行时,就会调用一次iterate()方法,若是存在多行,就会调用屡次。

// map阶段,迭代处理输入sql传过来的列数据
public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException;、

这是最精华的图,请屡次理解,而且结合代码推导过程。

这里写图片描述

其他资料参考。

http://www.cnblogs.com/ggjucheng/archive/2013/02/01/2888051.html
https://www.cnblogs.com/itxuexiwang/p/6264547.html