hive udf开发超详细手把手教程

hive udf开发超详细手把手教程关于 hive 的 udf 介绍 就不多啰嗦了 网上的教程一抓一大把 也可以上 apache 的官网去查阅相关资料 我就省了翻译的时间了 重点给大家带来干货 手把手教会你怎样开发一个 udf 函数 已经如何部署到服务器上的 hive 环境中运行 用最简单的话来说 就是教大家怎么让自己开发的 udf 跑起来 项目需求做数据挖掘项目中 常见的需求之一就是分析节假日订单跟平时订单的区别 于是 我们需要统计节假日订单的分布情况

关于hive的udf介绍,就不多啰嗦了。网上的教程一抓一大把,也可以上apache的官网去查阅相关资料,我就省了翻译的时间了。重点给大家带来干货,手把手教会你怎样开发一个udf函数,已经如何部署到服务器上的hive环境中运行。用最简单的话来说,就是教大家怎么让自己开发的udf跑起来。。。

项目需求

做数据挖掘项目中,常见的需求之一就是分析节假日订单跟平时订单的区别。于是,我们需要统计节假日订单的分布情况。但是hive中显然没有内置,也不可能内置此函数,因为每年的节假日都是变得嘛。于是,我们就需要自己开发一个udf来满足需求了。

配置文件

=元旦 =春节 =春节 =春节 =春节 =春节 =春节 =春节 =清明节 =清明节 =清明节 =五一劳动节 =五一劳动节 =五一劳动节 =端午节 =端午节 =端午节 =中秋节 =中秋节 =中秋节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =元旦 =元旦 =元旦 =春节 =春节 =春节 =春节 =春节 =春节 =春节 =清明节 =清明节 =清明节 =五一劳动节 =五一劳动节 =五一劳动节 =端午节 =端午节 =端午节 =中秋节 =中秋节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =元旦 =元旦 =元旦 =春节 =春节 =春节 =春节 =春节 =春节 =春节 =清明节 =清明节 =清明节 =五一劳动节 =五一劳动节 =五一劳动节 =端午节 =端午节 =端午节 =中秋节 =中秋节 =中秋节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 =国庆节 

以上包含有2014,2015,2016三年的假期。如果想增加,继续往此文件里添加就是。。。

新建maven项目

现在的java项目必须是用maven管理,方便又实用,谁用谁知道,不多解释。maven项目自然只需要知道pom.xml即可。pom文件如下:

 
   
   
     4.0.0 
    
   
     udf.leilei.elong.com 
    
   
     festival 
    
   
     1.0 
    
   
     hive 
    
   
     http://maven.apache.org 
    
    
    
      UTF-8 
     
    
    
     
     
       org.apache.hive 
      
     
       hive-exec 
      
     
       0.13.0 
      
     
     
     
       org.apache.hadoop 
      
     
       hadoop-common 
      
     
       2.5.0 
      
     
    
    
     
      
      
        org.apache.maven.plugins 
       
      
        maven-shade-plugin 
       
      
        2.2 
       
       
        
        
          package 
         
         
         
           shade 
          
         
         
         
        
       
      
     
    
   

提醒对maven不是很熟的同学们:因为我们项目里有依赖的jar包,所以必须加上 maven-shade-plugin 插件。当然你用 maven-assembly-plugin 也是没有问题的。如果你对maven不是那么熟悉,别管了,先粘过去,跑起来再说吧。。。

UDF具体代码开发

package festival; import java.io.InputStreamReader; import java.text.NumberFormat; import java.util.HashMap; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.hadoop.hive.ql.exec.UDF; public class FestivalType extends UDF{ private HashMap 
  
    festivalMap = new HashMap 
   
     (); public FestivalType() throws Exception { InputStreamReader propFile = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("festival_date.properties"), "UTF-8"); Properties prop = new Properties(); prop.load(propFile); for(Object key:prop.keySet()) { festivalMap.put(key.toString(), prop.getProperty(key.toString())); } } //解决double转string的科学计数法的问题 public String double_to_string(double dou) { Double dou_obj = new Double(dou); NumberFormat nf = NumberFormat.getInstance(); nf.setGroupingUsed(false); String dou_str = nf.format(dou_obj); return dou_str; } public String evaluate(double date_dou) { String date_str = this.double_to_string(date_dou); return evaluate(date_str); } public int evaluate(double date_dou,String flag) { String date_str = this.double_to_string(date_dou); return evaluate(date_str,flag); } public String evaluate(String date_str) { if (! this.match_date(date_str).equals("null")) { date_str = this.match_date(date_str); return festivalMap.get(date_str) == null ? "null" : festivalMap.get(date_str); } else { return "null"; } } public int evaluate(String date_str, String flag) { if (flag.equals("count") && ! this.match_date(date_str).equals("null")) { date_str = this.match_date(date_str); return festivalMap.get(date_str) == null ? 0 :1; } else { return 0; } } public String match_date(String date_str) { //匹配这种日期格式 Pattern pat_common = Pattern.compile("\\d{8}"); Matcher mat_common = pat_common.matcher(date_str); //匹配2016-01-01这种日期格式 Pattern pat_strike = Pattern.compile("\\d{4}-\\d{2}-\\d{2}"); Matcher mat_strike = pat_strike.matcher(date_str); //匹配 2016-01-01 10:35:46 这种日期格式 Pattern pat_colon = Pattern.compile("\\d{4}-\\d{2}-\\d{2}(\\s)+\\d{2}:\\d{2}:\\d{2}"); Matcher mat_colon = pat_colon.matcher(date_str); if (mat_colon.find()) { return date_str.replace("-", "").substring(0, 8); } else if(mat_strike.find()) { return date_str.replace("-", ""); } else if (mat_common.find()) { return date_str; } else { return "null"; } } //测试的main方法 public static void main(String[] args) throws Exception{ FestivalType fes = new FestivalType(); String date_str = ""; System.out.println(fes.evaluate(date_str)); String date_str1 = ""; String result = fes.evaluate(date_str1); System.out.println("result is:" + result); double date_dou = ; int result_dou = fes.evaluate(date_dou,"count"); System.out.println(result_dou); System.out.println(date_dou); } } 
    
  

将之前的配置文件放在src/main/resources下面,然后运行此代码,输出如下:

节日类型是:元旦 节日天数:1 

因为我们这篇文章的目的是让udf以最快的速度跑起来,所以udf具体实现细节以及原理就不多写了。大家记住下面一句话就可以:继承UDF类,重写evaluate方法,就可以了。

maven打包

上面代码测试通过以后,然后用maven打成jar包。如果是老司机,自然知道怎么做。如果是新司机,我偷偷告诉大家,eclipse里在项目上右击,选择 run as,然后maven install,maven就开始帮你打包了。如果是第一次,maven还会帮你把依赖的jar下载到本地仓库。打包完了以后,你就可以看到target目录下面出现了一个jar包,festival-1.0.jar。OK,这就是我们需要的jar包。

将jar包上传

接下来,我们将前面的jar包上传到服务器上的任何一个位置。比如我就是用scp命令,不多说。

使用udf查询

#!/bin/bash hive -e "add jar /home/xxx/lei.wang/festival-1.0.jar; create temporary function festival as 'festival.FestivalType'; set mapred.reduce.tasks = 10; select cast(a.create_date_wid as int) create_date_wid,sum(a.festival_order_num) from (select create_date_wid,festival(create_date_wid,'count') as festival_order_num from ora_dw_rewrite.olap_b_dw_hotelorder_f where create_date_wid>= and create_date_wid<=)a where a.festival_order_num > 0 group by a.create_date_wid order by create_date_wid;" 

为了达到快速上手的目的,直接上代码。

add jar /home/xxx/lei.wang/festival-1.0.jar; 

这一行是将jar包加进来,后面是你前面上传的路径地址

create temporary function festival as 'festival.FestivalType'; 

最后查询结果

.......... Stage-Stage-1: Map: 62 Reduce: 10 Cumulative CPU: 1547.44 sec HDFS Read:  HDFS Write: 1298 SUCCESS Stage-Stage-2: Map: 8 Reduce: 1 Cumulative CPU: 23.88 sec HDFS Read: 4608 HDFS Write: 205 SUCCESS Total MapReduce CPU Time Spent: 26 minutes 11 seconds 320 msec OK  xxx  xxx  xxx  xxx  xxx  xxx  xxx  xxx  xxx  xxx  xxx  xxx  xxx Time taken: 159.805 seconds, Fetched: 13 row(s) 

结束语

至此,一个完整的hive udf开发过程就结束了。当然还可以开发UDAF,限于时间有限,就不再详细介绍。欢迎有搞数据,算法的志同道合的同学们一起研究讨论

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/200458.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午10:48
下一篇 2026年3月20日 上午10:48


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号