Hive深入浅出UDAF

本文深入探讨了Hive中的UDAF(User Defined Aggregation Functions),解释了其处理多行输出一行数据的特性,并结合MapReduce进行类比。文章分析了AbstractGenericUDAFResolver和GenericUDAFEvaluator类的作用,以及ObjectInspector和Model在UDAF过程中的角色。此外,通过GenericUDAFSum的实现,阐述了UDAF的开发步骤和运行流程。
摘要由CSDN通过智能技术生成

上一篇我们讲解了基本UDF的编写,这一节我们来看下UDAF[User Defined Aggregation Functions],自定义聚合函数,用来处理输入多行,输出一行的操作,类似MapReduce中Reduce操作。UDAF是需要在hive的sql语句和group by联合使用,hive的group by对于每个分组,只能返回一条记录。

概述

Hive是构建在Hadoop上的数据仓库,我们的sql语句最终都是要变成Mapreduce函数,只不过hive已经帮助我们写好并隐藏mapreduce ,给我们提供简洁的sql函数,所以我们要结合MapperCombinerReducer来帮助我们理解UDAF函数。在hadoop集群中有若干台机器,在不同的机器上MapperReducer任务独立运行。所以大体上来说,这个UDAF函数读取数据[mapper],聚集一堆mapper输出到部分聚集结果[combiner],并且最终创建一个最终的聚集结果[reducer]。因为我们跨域多个combiner进行聚集,所以我们需要保存部分聚集结果。在实现UDAF时候,Hive提供了两个重要的类org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolverorg.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator,我们先分析这两个类都做了什么工作,然后通过一个简单的例子来了解如何自定义UDAF。

UDAF重要的类及原理分析

AbstractGenericUDAFResolver

AbstractGenericUDAFResolver很简单,要覆盖实现getEvaluator方法,该方法会根据sql传递的参数数据格式指定调用哪个Evaluator进行处理

public GenericUDAFEvaluator getEvaluator(TypeInfo[] info) 
  throws SemanticException {
   
  throw new SemanticException(
    "This UDAF does not support the deprecated getEvaluator() method.");
}

GenericUDAFEvaluator

所有Evaluator必须继承抽象类org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator。子类必须实现它的一些抽象方法,实现UDAF的逻辑。

ObjectInspector

ObjectInspector作用主要是解耦数据使用与数据格式,使得数据流在输入输出端切换不同的输入输出格式,不同的Operator上使用不同的格式,可以通过这个抽象类知道上游传递过来的参数类型,从而解耦。一个ObjectInspector对象本身并不包含任何数据,它只是提供***对数据的存储类型说明***和***对数据对象操作***的统一管理或者是代理。

public interface ObjectInspector extends Cloneable {
   
  String getTypeName();

  ObjectInspector.Category getCategory();

  public static enum Category {
   
    PRIMITIVE,
    LIST,
    MAP,
    STRUCT,
    UNION;

    private Category() {
   
    }
  }
}

Model

Model代表了UDAF在Mapreduce的各个阶段,定义如下:

public static enum Mode {
   
  // PARTIAL1: from original data to partial aggregation data: iterate() and t
  // erminatePartial() will be called.
  PARTIAL1,
  // PARTIAL2: from partial aggregation data to partial aggregation data: 
  // merge() and terminatePartial() will be called. 
  PARTIAL2,
  // FINAL: from partial aggregation to full aggregation: merge() and
  // terminate() will be called. 
  FINAL,
  // COMPLETE: from original data directly to full aggregation: iterate() and
  // terminate() will be called.
  COMPLETE
};

我们来详细分析下各个阶段:

  1. PARTIAL1是map阶段,从原始数据到数据聚合,将会调用iterateterminatePartial方法;
  2. PARTIAL2相当于map阶段的Combine,负责map端合并map的数据,将调用mergeterminatePartial方法;
  3. FINAL相当于reduce阶段,从部分聚合到完全聚合,将会调用mergeterminate方法;
  4. COMPLETE这个表示mapreduce中只有map没有reduce,直接在map端就得到结果了,从原始数据直接到完全聚合结果,将会调用iterateterminate方法。

所以,完整的UDAF逻辑是一个mapreduce过程,如果有mapper和reducer,就会经历PARTIAL1(mapper),FINAL(reducer),如果还有combiner,那就会经历PARTIAL1(mapper),PARTIAL2(combiner),FINAL(reducer)。而有一些情况下只有mapper,而没有reducer,所以就会只有COMPLETE阶段,这个阶段直接输入原始数据,出结果。<

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值