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 的缺点

  • 相关阅读:
    进程和线程
    yum安装apache后更改worker模式
    (转)top命令详解
    虚拟机linux在关机不正常的情况下出现的问题
    mysql赋予用户权限grant all privileges on
    lampp自带mysql远程访问问题
    扫盲
    linux常用命令使用
    剑指Offer对答如流系列
    剑指Offer对答如流系列
  • 原文地址:https://www.cnblogs.com/yanshw/p/11904601.html
Copyright © 2011-2022 走看看