感谢兄弟们的关注与支持,如果觉得有帮助的话,还请来个点赞、收藏、转发三操作
该文章已更新到语雀中,后台回复“语雀”可获取进击吧大数据整个职业生涯持续更新的所有资料
感谢
首先感谢linxiang同学提供的文章素材,linxiang在一次课上抛出了这样一个问题"在面试过程中,面试官问到我UDF是在Map端执行的,还是在Reduce端执行的"。我刚听到这个问题的时候,有点没反应过来,因为这个问题确实平时没有去思考过,后来仔细想了下,才有了现在的这篇文章。通过本文,你将可以了解到:
1、UDF和UDAF和UDTF之间的区别
2、UDF和UDAF和UDTF在运行过程中分别是在哪端执行的?
3、UDF和UDAF和UDTF在各个Hive版本中的内置函数(共175项函数)
4、UDF和UDAF和UDTF在日常开发中的实操
UDF、UDAF、UDTF的区别
UDF
UDF全称为User Defined Function(即用户自定义函数),UDF开发在日常工作当中是非常普遍的。我们写一段SQL,调用UDF,得到结果就算是结束了,但大家有没有想过UDF底层是怎么执行的呢?那么我们拿MR引擎为例,那UDF是在Map端执行还是在Reduce端执行的呢?说实话,我之前没想过。
既然没想过,那今天就来想一想。首先抛开在哪端执行不说,那我们知道UDF的模式是我们给一个值,然后再返回一个值。如上图所示,传一个A,返回给一个A_1;传一个B,返回给一个B_1;传一个C返回给一个C_1;这种模式就相当于在传入的一个值上进行了一些修饰后再返回给我们,相当于是一对一的模式。梳理到这里,答案也比较清晰了,这不就是map功能吗。有些同学可能会质疑,没关系,我们explain一下就知道了。

如上图所示,只有一个fetch Operator,当然这个demo比较简单,不会走MR的。从这里也可以看出来这就是一个转换功能,但有些同学仍有疑惑,没关系,让我们来一个走MR的例子。
explain select substr(id,2),count(1) from test group by substr(id,2);
到这里总能证明UDF函数是在Map阶段执行的吧!
UDAF
UDAF全称为User-defined Aggregation Function,从命名来看,这是一种聚合函数,比如像我们常用的sum、max。如下图所示,可以抽象的理解成传入多个值,最后返回给我们一个值。那么对于该类型的函数是不是一定在reduce端执行了,为什么这么说呢?你看sum函数是不是会发生shuffle,是不是在reduce端做全局聚合呢(如果你这样想也没问题,但也有问题)
我们通过explain命令来验证一下想法。我们执行如下命令:
explain select sum(id) from test
如上图所示,对于SUM类型的UDAF是在map端和reduce端都执行了,哎呦,这是怎么回事呢?我们回想一下MapReduce机制,如果我们要做全局聚合,难道要把所有的数据都拉取到reduce端吗?那reduce端压力是不是就会很大。所以有了局部聚合的这么一种优化方式。
那我们把局部聚合优化阶段给关闭后,再来看一下UDAF会在那一端执行
--关闭map端聚合
set hive.map.aggr=false;
如上图所示,当我们把局部聚合优化功能给关闭后,UDAF只会在reduce执行。
UDTF
UDTF全称为User-defined Table Generating Function,该模式的功能是通过输入一行,返回多行。在实际场景中用的不多,该类型的执行阶段通常是在本地,大家也可以理解成是做map转换和UDF是一样的阶段。
我们仍然用示例sql通过explain命令来验证一下
explain select explode(array(1,2,3,45));

区别总结
ok,到了这里不知道大家对三种F的端执行类型是否有一些清晰的认识,这里再次做一些总结:
1、对于UDF来说,也就是大家通常认知的map转换功能,一般是在task本地执行,不会发生shuffle,一句话概括就是map端执行。
2、对于UDAF来说,通常是聚合类函数,那么就会发生shuffle网络传输,如果不做任何优化的话,只在reduce端执行,如果开启了局部优化,那么map端和reduce端都会执行。
3、对于UDTF来说,属于数据炸裂,可以和UDF同样认为都是在map端执行的。
各版本内置函数列表
注意:Hive中所有的关键词都是忽略大小写的。无论是通过Beeline还是CLI模式,都可以通过以下命令来查看Hive 函数
-- 查看所有的函数
show functions;
---查看具体某个函数的帮助手册
desc function function_name;
--查看函数示例功能
desc function extended function_name;
注意点:当hive.cache.expr.evaluation参数设置为true的时候(当然默认值就是true),在0.12.0、0.13.0和0.13.1版本中,使用UDF嵌套到其他UDF函数中可能会有问题。具体可以见HIVE-7314
一、内置UDF函数
1.1、数学函数
注意:当传入值为NULL的时候,返回值大多数也是NULL;
| 支持版本+ | 返回值类型 | 函数名称 | 功能描述 |
|---|---|---|---|
| DOUBLE | abs(DOUBLE a) | 返回绝对值 | |
| Hive0.13.0 | DOUBLE | acos(DOUBLE a), acos(DECIMAL a) | 如果 -1<=a<=1 或 NULL,则返回 a 的反余弦值。 |
| Hive0.13.0 | DOUBLE | asin(DOUBLE a), asin(DECIMAL a) | 如果 -1<=a<=1 或 NULL,则返回 a 的反正弦。 |
| Hive0.13.0 | DOUBLE | atan(DOUBLE a), atan(DECIMAL a) | 返回a的正切值。 |
| STRING | bin(BIGINT a) | 返回二进制格式的数字 | |
| Hive1.3.0 | DOUBLE | bround(DOUBLE a) | 使用HALF_EVEN四舍五入模式返回a的BIGINT值。例如:bround(2.5) = 2, bround(3.5) = 4. |
| Hive1.3.0 | DOUBLE | bround(DOUBLE a, INT d) | 使用HALF_EVEN四舍五入模式返回一个四舍五入到小数点后d位的数值。例如:bround(8.25, 1) = 8.2,bround(8.35, 1) = 8.4 |
| Hive1.2.0 | DOUBLE | cbrt(DOUBLE a) | 返回双精度值的立方根 |
| BIGINT | ceil(DOUBLE a), ceiling(DOUBLE a) | 返回等于或大于 a 的最小 BIGINT 值 | |
| STRING | conv(BIGINT num, INT from_base, INT to_base), conv(STRING num, INT from_base, INT to_base) | 将一个数字从一个给定的基数转换为另一个基数 | |
| Hive0.13.0 | DOUBLE | cos(DOUBLE a), cos(DECIMAL a) | 返回 a 的余弦(a 以弧度为单位) |
| Hive0.13.0 | DOUBLE | degrees(DOUBLE a), degrees(DECIMAL a) | 将 a 的值从弧度转换为度数 |
| DOUBLE | e() | 返回 e 的值。 | |
| Hive0.13.0 | DOUBLE | exp(DOUBLE a), exp(DECIMAL a) | 返回 ea,其中 e 是自然对数的底数 |
| Hive1.2.0 | BIGINT | factorial(INT a) | 返回a的阶乘 |
| BIGINT | floor(DOUBLE a) | 返回等于或小于 a 的最大 BIGINT 值。 | |
| Hive1.1.0 | T | greatest(T v1, T v2, …) | 返回值列表的最大值 |
| STRING | hex(BIGINT a) hex(STRING a) hex(BINARY a) | 如果参数是 INT 或二进制,则十六进制将数字作为十六进制格式的 STRING 返回。否则,如果数字是 STRING,它会将每个字符转换为其十六进制表示并返回结果 STRING。 | |
| T | least(T v1, T v2, …) | 返回值列表的最小值 | |
| Hive0.13.0 | DOUBLE | ln(DOUBLE a), ln(DECIMAL a) | 返回参数 a 的自然对数 |
| Hive0.13.0 | DOUBLE | log2(DOUBLE a), log2(DECIMAL a) | 返回参数 a 的以 2 为底的对数 |
| Hive0.13.0 | DOUBLE | log10(DOUBLE a), log10(DECIMAL a) | 返回参数 a 的以 10 为底的对数 |
| DOUBLE | log(DOUBLE base, DOUBLE a) | ||
| log(DECIMAL base, DECIMAL a) | 返回参数 a 的底对数 | ||
| INT or DOUBLE | negative(INT a), negative(DOUBLE a) | 返回-a。 | |
| DOUBLE | pi() | 返回π的值 | |
| INT or DOUBLE | pmod(INT a, INT b), pmod(DOUBLE a, DOUBLE b) | 返回 a mod b 的正值 | |
| INT or DOUBLE | positive(INT a), positive(DOUBLE a) | 返回a | |
| DOUBLE | pow(DOUBLE a, DOUBLE p), power(DOUBLE a, DOUBLE p) | 返回 ap | |
| 它返回 a值的 p 次幂 | |||
| Hive0.13.0 | DOUBLE | radians(DOUBLE a), radians(DOUBLE a) | 将 a 的值从度数转换为弧度 |
| DOUBLE | rand(), rand(INT seed) | 返回从 0 到 1 均匀分布的随机数(从行到行变化)。指定种子将确保生成的随机数序列是确定性的 | |
| DOUBLE | round(DOUBLE a) | 返回a的四舍五入的BIGINT值 | |
| DOUBLE | round(DOUBLE a, INT d) | 返回四舍五入到 d 位小数 | |
| Hive1.2.0 | INT | ||
| BIGINT | shiftleft(TINYINT | SMALLINT | |
| Hive1.2.0 | INT | ||
| BIGINT | shiftright(TINYINT | SMALLINT | |
| Hive1.2.0 | INT | ||
| BIGINT | shiftrightunsigned(TINYINT | SMALLINT | |
| Hive0.13.0 | DOUBLE or INT | sign(DOUBLE a), sign(DECIMAL a) | 将 a 的符号返回为“1.0”(如果 a 为正)或“-1.0”(如果 a 为负),否则返回“0.0”。十进制版本返回 INT 而不是 DOUBLE |
| Hive0.13.0 | DOUBLE | sin(DOUBLE a), sin(DECIMAL a) | 返回 a 的正弦值(a 以弧度为单位 |
| Hive0.13.0 | DOUBLE | sqrt(DOUBLE a), sqrt(DECIMAL a) | 返回 a 的平方根 |
| Hive0.13.0 | DOUBLE | tan(DOUBLE a), tan(DECIMAL a) | 返回a的正切值(a的单位是弧度) |
| Hive0.12.0 | BINARY | unhex(STRING a) | 十六进制的倒数。将每对字符解释为一个十六进制数并转换为该数的字节表示 |
| Hive3.0.0 | INT | width_bucket(NUMERIC expr, NUMERIC min_value, NUMERIC max_value, INT num_buckets) | 通过将 expr 映射到第 i 个相同大小的存储桶,返回 0 到 num_buckets+1 之间的整数。通过将 [min_value, max_value] 分成大小相等的区域来制作桶。如果expr < min_value,返回1,如果expr > max_value 返回num_buckets+1 |
1.1.1、abs
作用:返回绝对值
select abs(-1),abs(1);

1.1.2、acos–>从Hive0.13.0
作用:如果 -1<=a<=1 或 NULL,则返回 a 的反余弦值。
select acos(0.1),acos(-1),acos(1),acos(-0.6)

1.1.3、asin–>从Hive0.13.0
作用:如果 -1<=a<=1 或 NULL,则返回 a 的反正弦。
select asin(0.1),asin(-1),asin(1),asin(-0.6),asin(null);

1.1.4、atan–>从Hive0.13.0
select atan(1.1),atan(0.543535)

1.1.5、bin
select bin(234234324234);

1.1.6、bround–>Hive1.3.0
select bround(2.4),bround(2.5),bround(3.5),bround(3.6554),bround(8.324,2),bround(3.234,1);
1.1.7、cbrt–>Hive1.2.0
select cbrt(3.34543);

1.1.8、ceil
select ceil(2.234),ceil(2.65),ceil(3.343);

1.1.9、conv
select conv(234234,10,2),conv(234234,10,16);

1.1.10、cos–>Hive0.13.0
select cos(23.23),cos(60),cos(90),cos(180);

1.1.11、degress–>Hive0.13.0
select degrees(23.23432),degrees(23.66545);

1.1.12、e
select e();

1.1.13、exp–>Hive0.13.0
select exp(23.234),exp(23.354),exp(23.65),exp(2);

1.1.14、factorial–>Hive1.2.0
1.1.15、floor
select floor(2.34),floor(2.756),floor(3.54);

1.1.16、greatest–>Hive1.1.0
select greatest(1,2,34,45,234,342,42324);

1.1.17、hex
select hex(23),hex(2);

1.1.18、least
select least(1,2,34,45,234,342,42324);

1.1.19、ln–>Hive0.13.0
select ln(10),ln(20),ln(0),ln(1);

1.1.20、log2–>Hive0.13.0
select log2(4),log2(6),log2(8);

1.1.21、log10–>Hive0.13.0
select log10(40),log10(60),log10(80),log10(100);

1.1.22、negative
select negative(1),negative(20.234),negative(-20);

1.1.23、pi
select pi();

1.1.24、pmod
select pmod(10,2),pmod(10,3),pmod(10,4);

1.1.25、positive
select positive(20),positive(10.234353);

1.1.26、pow
select pow(5,2),pow(4,2);

1.1.27、radians–>Hive0.13.0
select radians(4),radians(180),radians(360);

1.1.28、rand
-- 可以指定种子序列,这样可以保障每次的结果都一致
select rand(),rand(5),rand(10);

1.1.29、round
select round(3),round(3.2),round(3.43);


本文深入探讨Hive中的用户自定义函数(UDF)、用户自定义聚合函数(UDAF)和用户自定义表生成函数(UDTF)。详细讲解了它们之间的区别、执行阶段、内置函数以及在不同Hive版本中的用法。通过示例展示了如何使用这些函数进行数据操作,如字符串处理、日期函数、集合函数等。同时,还介绍了如何自定义开发UDF、UDAF和UDTF,以满足特定的数据处理需求。
最低0.47元/天 解锁文章
1823






