大数据实战第七课-Hive执行流程&UDF函数

一、上次课回顾
二、Hive SQL执行流程
三、Hive UDF函数
Permanent Function(持久化的函数)

一、上次课回顾

https://blog.csdn.net/zhikanjiani/article/details/93417994

二、Hive执行流程分析

Spark SQL、Impla、Hive的执行流程大体相似.

Hive SQL执行流程分析:
1)SQL执行流程分析
2)面试用

常用的SQL语句:
select yyy, 聚合函数 from XXX group by yyyy;
select a., b. from a join b on a.id = b.id;

抽象语法树:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain

ABSTRACT SYNTAX TREE(抽象语法树):

	 (TOK_QUERY (TOK_FROM (TOK_TABREF src)) 
	 (TOK_INSERT (TOK_DESTINATION (TOK_TAB dest_g1))
	 (TOK_SELECT (TOK_SELEXPR (TOK_COLREF src key)) 	
	 (TOK_SELEXPR (TOK_FUNCTION sum (TOK_FUNCTION substr 
	 (TOK_COLREF src value) 4)))) 
	 (TOK_GROUPBY (TOK_COLREF src key))))

在这里插入图片描述
面试题1:Predicate Push Down和Mapjoin分别执行在哪两个上???
PK哥在面试过程中join使用SQL来描述,问题:给你一个join的功能,使用mapjoin和reduce join来实现。

SQL要熟练到怎样的一个程度???
看到一个SQL要知道它的底层是怎么样的;使用MapReduce的思想来理解出来

给定SQL语句:
从抖音的访问日志表,带大奔的有哪些???
select * from access a where a.day=‘20190414’ and a.catalog=‘大奔’;

表最终是落地在hdfs上的,必然是要去hdfs上读取数据的;
还涉及一个概念:输入分片(inputSplit)
这个SQL语句没有shuffle,仅仅只是过滤而已.

2.1:无Shuffle

SQL语句修改,找出哪个城市ID,城市名字
==>select a.id,a.city from access

解释:SQL语句进来有两个分片,MapTask底层是两个map;两个分片的数据存放在hdfs上,分成两个MapTask,底层是以进程的方式运行;两个InputSplit对应两个Map;
2)我们看SQL中的where条件,a.day=‘20190414’,分区就是hdfs上的目录,第一步就不用执行了;
3)Map中的逻辑:拆分:split("\t")、
splits(2):if collect(…)
此时就已经找到了分片1中的大奔,分片2中的大奔
==> 类似于ETL,
4)SQL输出:如下图
在这里插入图片描述

2.2:有Shuffle

group by
select city ,count(1) from access
where day=‘20190414’ and cate=‘大奔’
group by city

mr count:

  1. map:split ==> (word,1)
  2. shuffle:(Word,1) partitioner ==> reduce
  3. reduce:(word,可迭代的(1,1,1,1,1,1,1))
    ==> (word, sum(可迭代的))

转换到业务需求上来是不是一样的呢了,是的
map:split ==> (city,1)
combiner:local reduce (局部聚合)

本节面试题:combiner的使用场景
Spark中reduceByKey和GroupByKey的区别
reduceByKey:全量数据聚合经过shuffle.
GroupByKey:先做一个局部聚合,本地有combiner操作.

Shuffle(洗牌)操作:可以参考我之前的博客查看:
在这里插入图片描述

split去读取数据,map,经过combiner计算每个task结果,根据partition的定义分到reduce上,最终结果落地HDFS,这就是group by的过程
感觉有点像mapreduce的wordcount.

SQL中的JOIN操作见后续:

穿插:WordCount需要Combiner

三、UDF函数

工作流程:
1)开发代码
2)本地测试
3) 打包代码

在工作中,Hive中的函数满足不了业务上的需求,所以需要我们自己去开发UDF函数,Hive是使用Java开发的。

分为三类:
UDF(User-Defined Function):one-to-one row mapping upper substr 一行对一行的映射
UDAF:Aggregation(聚合) Many-to-one row mapping sum/min
UDTF:Table-generating one-to-many lateral view explode()

使用IDEA打开mapreduce ETL的项目:
1、在pom.xml中添加如下:

<properties>
      <hive.version>1.1.0-cdh5.7.0</hive.version>
  </properties>
  
<dependency>
          <groupId>org.apache.hive</groupId>
          <artifactId>hive-exec</artifactId>
          <version>${hive.version}</version>
          <scope>test</scope>
      </dependency>

2、编写简单的HelloUDF.java

package com.ruozedata.hadoop.udf;


import org.apache.hadoop.hive.ql.exec.UDF;

public class HellloUDF extends UDF {
    /*
    *需求:输入:若泽
    * 输出:hello:若泽
     */

    public String evaluate(String input){
        return "hello" + input;
    }

    public static void main(String[] args) {
        HellloUDF udf = new HellloUDF();
        String output = udf.evaluate("若泽");
        System.out.println(output);
    }
}

3、打包本地提交jar包到阿里云服务器:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateFunction
在Hive中执行:

1、create temporary function sayHello AS 'com.ruozedata.hadoop.udf.HellloUDF';
hive (g6_hadoop)> create temporary function sayHello AS 'com.ruozedata.hadoop.udf.HellloUDF';
FAILED: Class com.ruozedata.hadoop.udf.HellloUDF not found
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.FunctionTask

2、执行这个命令前需要先添加jar包:
hive (g6_hadoop)> ADD JAR /home/hadoop/lib/g6-hadoop-1.0.jar;
Added [/home/hadoop/lib/g6-hadoop-1.0.jar] to class path
Added resources: [/home/hadoop/lib/g6-hadoop-1.0.jar]

3、再次执行命令:
 create temporary function sayHello AS 'com.ruozedata.hadoop.udf.HellloUDF';

还报了一个错:java.lang.UnsupportedClassVersionError: com/ruozedata/hadoop/udf/HellloUDF : Unsupported major.minor version 52.0
FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.FunctionTask. com/ruozedata/hadoop/udf/HellloUDF : Unsupported major.minor version 52.0

因为我们本地运行程序是jdk1.8;这套环境jdk1.7;切换下版本即可;更换版本后还是这个问题,换了台机器没问题,不知道重启下集群,重启hive有没有用。

4、show functions;
已经显示有sayhello了,它会自动把大写转换为小写。

5、测试:
hive (ruozeg6)> create table dual(x string);
OK
Time taken: 1.696 seconds
hive (ruozeg6)> insert into table dual values('');
hive (ruozeg6)> select sayhello("ruozedata") from dual;
OK
hello:ruozedata

注意:创建的是临时function,所以只对当前session生效,重新开一个session是不生效的。

解决:…

Permanent Function(持久化的函数)

hive的元数据库mysql中有一张表专门用来存放函数的,此时表信息如下:
mysql> use ruoze_g6;
Database changed
mysql> select * from funcs;
Empty set (0.00 sec)

创建永久函数:
1、CREATE FUNCTION sayhello2 AS 'com.ruozedata.hadoop.udf.HellloUDF' USING JAR 'hdfs://hadoop004:9000/lib/g6-hadoop-1.0.jar';


hive (ruozeg6)> CREATE FUNCTION sayhello2 AS 'com.ruozedata.hadoop.udf.HellloUDF' USING JAR 'hdfs://hadoop004:9000/lib/g6-hadoop-1.0.jar';
converting to local hdfs://hadoop004:9000/lib/g6-hadoop-1.0.jar
Added [/tmp/23c0c2e6-8329-4d87-a025-966920086afd_resources/g6-hadoop-1.0.jar] to class path
Added resources: [hdfs://hadoop004:9000/lib/g6-hadoop-1.0.jar]
OK
Time taken: 1.046 seconds

如下图:我们可以看到自定义的永久函数在mysql数据库中的ruoze_g6元数据库下的funcs表中显示:
在这里插入图片描述
当前session启动测试:select sayhello2(“ruozedata”) from dual;
在这里插入图片描述

新开一个session来启动Hive,如下图所示
在这里插入图片描述

对于UDF所需要的掌握程度:
开发代码
继承:extends UDF
重写 evaluate
本地测试
main方法
打包
上传服务器测试

Hive中自带的函数IDEA的体现:
FunctionRegistry.java

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值