zoukankan      html  css  js  c++  java
  • Hive 教程(十)-UDF

    hive 虽然自带了很多函数,但是毕竟有限,无法满足所有业务场景,用户可以自定义函数来实现特定功能

    UDF

    user define function,用户自定义函数

    可以分为 3 类

    UDF:一进一出

    UDAF:聚集函数,多进一出,user define aggregation function

    UDTF:炸裂函数,一进多出

    UDF 可以用多种语言实现,如 java、python、hive

    准备工作

    建表

    create external table person(
    name string,
    idcard string)
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '	'
    STORED as TEXTFILE;

    外建表,还记得吗?

    外建表不能 truncate 清空,如果是 drop 删表,只删除元数据,hdfs 中的数据还在

    写入如下数据

    neil    411326199402110030
    pony    41132519950911004x
    jcak    12312423454556561
    tony    412345671234908

    Hive Function

    即用 hql 来实现 function,这是最简单的,写完 function 直接运行 sql 就行了

    select idcard,
    case when length(idcard) = 18 then
                 case when substring(idcard,-2,1) % 2 = 1 then '' 
                 when substring(idcard,-2,1) % 2 = 0 then '' 
                 else 'unknown' end 
         when length(idcard) = 15 then 
                case when substring(idcard,-1,1) % 2 = 1 then ''
                when substring(idcard,-1,1) % 2 = 0 then ''
                else 'unknown' end
         else '不合法' end 
    from person;

    Python UDF

    python 也毕竟简单,类似于 mapreduce

    # -*- coding: utf-8 -*-
    import sys
    
    for line in sys.stdin:
        detail = line.strip().split("	")
        if len(detail) != 2:
            continue
        else:
            name = detail[0]
            idcard = detail[1]
            if len(idcard) == 15:
                if int(idcard[-1]) % 2 == 0:
                    print("	".join([name,idcard,""]))
                else:
                    print("	".join([name,idcard,""]))
            elif len(idcard) == 18:
                if int(idcard[-2]) % 2 == 0:
                    print("	".join([name,idcard,""]))
                else:
                    print("	".join([name,idcard,""]))
            else:
                print("	".join([name,idcard,"身份信息不合法!"]))

    输入就是 hive 表的每一行

    本地测试 UDF

    直接在 hive 上测试比较麻烦,我们可以在本地测试下 UDF 写的是否正确,直接命令行即可

    cat person.txt|python person.py

     

    hive 中使用 UDF

    在 hive 中使用 python 编写的 UDF 需要借助 transform 函数,语法如下

    SELECT TRANSFORM (<columns>)
    USING 'python <python_script>'
    AS (<columns>)
    FROM <table>;

    顾名思义,就是用 python 脚本来转换 某列 生成新的列作为输出

    第一步:加载 py 文件

    在 hive 中执行如下代码

    add file /xxx/udf1.py

    xxx 为本地路径;

    注意在每次启动 hive 后都要重新加载

    第二步:使用 UDF 查询

    select transform(name,idcard) USING 'python udf1.py'  AS (name,idcard,gender) from person;
    neil    411326199402110030    男
    pony    41132519950911004x    女
    jcak    12312423454556561    身份信息不合法!
    tony    412345671234908    女

    vs1

    select transform(name,idcard) USING 'python udf1.py'  AS (name,idcard) from person;
    neil    411326199402110030
    pony    41132519950911004x
    jcak    12312423454556561
    tony    412345671234908

    vs2

    select transform(name) USING 'python udf1.py'  AS (name,idcard,gender) from person;

    可执行,但是无输出

    转换的列和输出的列在一定程度上保持一致

    python UDF 是效率比较低的,因为python 直接向系统请求资源,而不是通过 yarn 的 rm 申请,对资源的利用率较低

    Java UDF 

    见官网

    参考资料:

    https://cwiki.apache.org/confluence/display/hive/hiveplugins  官网  java 用法

    https://blog.csdn.net/qq_26937525/article/details/54136317

    https://blog.csdn.net/liu82327114/article/details/80670415  讲述了 python udf 的缺点

  • 相关阅读:
    Vue(小案例_vue+axios仿手机app)_go实现退回上一个路由
    nyoj 635 Oh, my goddess
    nyoj 587 blockhouses
    nyoj 483 Nightmare
    nyoj 592 spiral grid
    nyoj 927 The partial sum problem
    nyoj 523 亡命逃窜
    nyoj 929 密码宝盒
    nyoj 999 师傅又被妖怪抓走了
    nyoj 293 Sticks
  • 原文地址:https://www.cnblogs.com/yanshw/p/11904601.html
Copyright © 2011-2022 走看看