前言
离线数仓之前的主力工具是hive,有一些处理需要写udf实现,当hive sql迁移成spark sql时。之前的udf函数该怎么办呢,本文为自测并总结。
结果写在前面,hive jar包可以直接复用,不用重新编写。
环境: spark2.11,hive2.3.6,hadoop2.7.2
解决方案
首先,hive的元数据一般生产我们都会存在mysql当时,所以设想:spark on hive也是使用hive的元数据,可以看到hive的表,那如果将hive的udf注册成hive的永久函数,spark on hive直接访问能不能使用呢?
-
步骤1:hive udf准备
打包hive udf,上传至hdfs:/udf目录
hadoop fs -mkdir -p /test/hive/udf
hadoop fs -put hive-function-1.0-SNAPSHOT.jar /test/hive/udf
-
步骤2:注册永久hive函数
进入hive shell
create function my_udf_test as 'com.iszhaoy.udf.StringUtilsUDF' using jar 'hdfs:/test/hive/udf/hive-function-1.0-SNAPSHOT.jar';
Added [/tmp/7b67f128-2bce-4d9f-86f9-5a4cbfc3bdcb_resources/hive-function-1.0-SNAPSHOT.jar] to class path
Added resources: [hdfs:/test/hive/udf/hive-function-1.0-SNAPSHOT.jar]
OK
Time taken: 0.038 seconds
-
步骤3:查看hive元数据
mysql的FUNCS和DBS表,如下 :
这里要注意的是,函数不跨库。在default注册的函数,只能在default库下使用。
-
spark sql 测试
本地搭建maven环境,并引入core-site.xml,hdfs-site.xml,hive-site.xml。
spark.sql("select my_udf_test('ABC')").show(false)
还有一种方式,可以在spark sql运行时注册临时函数,还是先将hive jar上传hdfs,项目引入core-site.xml,hdfs-site.xml,hive-site.xml
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()); spark.sql("create function my_udf as 'com.iszhaoy.udf.StringUtilsUDF' using jar 'hdfs:/test/hive/udf/hive-function-1.0-SNAPSHOT.jar'")
即可使用。
如何知道现有的hive udf的资源路径呢?
在mysql管理的元数据中,FUNCS,FUNC_RU两张表为记录hive udf元数据的表信息。可通过
SELECT a.FUNC_ID, a.FUNC_NAME, b.RESOURCE_URI
FROM (
SELECT *
FROM FUNCS
WHERE FUNC_NAME = 'my_udf_test'
) a
LEFT JOIN FUNC_RU b ON a.FUNC_ID = b.FUNC_ID
总结
本文自测并总结了hive数据仓库迁移spark sql后udf的迁移情况,可以利用spark on hive 共享mysql元数据的特点,通过注册永久函数或者在代码注册临时函数,这样不必重新写一套spark的udf,使用原有的hive jar即可。
-- by 俩只猴