分享

Hive的Transform应用

 CDA数据分析师 2023-05-18 发布于北京


  CDA数据分析师 

什么是Transform

       会使用Python做数据处理的小伙伴一定使用过自己定义的函数去加工处理数据。在hive中的自定义函数支持Transform和UDF。UDF是将java代码打包上传,如果你不想或不会写java代码也可以,那就用到了Transform,写一个脚本,通过脚本(Python、shell)来处理数据。
       transform的原理可以追溯到Hadoop的Streaming架构,Hadoop Streaming框架,最大的好处是,让任何语言编写的map, reduce程序能够在hadoop集群上运行;map/reduce程序只要遵循从标准输入stdin读,写出到标准输出stdout即可。其次,容易进行单机调试,通过管道前后相接的方式就可以模拟streaming, 在本地完成map/reduce程序的调试。
      那么transform本质上也是一种Streaming,Hive用户可以使用Transform关键字在字符数据流中插入自己定义的map和reduce程序。在使用Transform的时候,默认情况下,在数据输入到用户自定义的脚本之前,列将转换为STRING并由TAB分隔;
      类似地,所有NULL值都将转换为文本字符串\N,以便区分NULL值和空字符串。用户脚本的标准输出将被视为TAB分隔的STRING列,任何仅包含\N的单元格将被重新解释为NULL,然后生成的STRIG列将以通常的方式转换为表声明中指定的数据类型。用户脚本可以将调试信息输出为标准错误,该错误将显示在hadoop的任务详细信息页面上。
本位采用Python这个在数据科学应用较多的语言去写脚本,Python如何获取Hive传入的数据呢?Python中是有标准输入这样的东东的,它在sys模块中。我们获取数据的代码可以这样写:
import sys
for line in sys.stdin:
   pass # 后续写我们的处理逻辑就可以了
Hive会自动把数据传过来,各个列之间由TAB间隔,也就是\t。
引用官方示例说明使用方法:

这是一个类似streaming的功能,但是可以更方便的访问Hive中的数据,也可以把SQL语句和自写脚本整合在一起运行。
简单分析 官网 上的一个例子
FROM (
FROM pv_users
SELECT TRANSFORM(pv_users.userid, pv_users.date)
USING 'map_script'
AS dt, uid
CLUSTER BY dt
) map_output
INSERT OVERWRITE TABLE pv_users_reduced
SELECT TRANSFORM(map_output.dt, map_output.uid)
USING 'reduce_script'
AS date, count;
这段代码的大致工作流程描述如下:
map_script 作为mapper, reduce_script 作为reducer。将 pv_users 表中的 userid , date两列作为mapper的输入字段,处理后的输出的前两个字段分别命名为 dt , uid ,并按照 dt 字段作partition和sort送给reduce阶段处理。reducer的输入字段为 dtuid ,输出处理后的前两个字段,并命名为 date , count ,写入到 pv_users_reduced 表中。
这里有几个细节:
  • mapper和reducer用到的script可以是任何可执行文件。注意 如果用到的是本地文件,应当在语句开始前用 ADD FILEADD FILES 将文件加入进来
  • mapper和reducer的输入输出都是以TAB为分隔符
  • 如果 USING 'script’ 语句后面没有 AS ,则Hive默认 script 的输出中第一个TAB之前的字段为key,后面的部分全部为value。若指定了 AS ,则严格按照 AS 后面的字段数输出,例如AS dt, uid ,则输出前两个字段并忽略后面的字段。此外, AS 语句可以指定数据类型,如AS (date STRING, count INT) 。默认都是 string 类型。
  • CLUSTER BY 关键字是 DISTRIBUTE BYSORT BY 的简写,这两者可以认为对应与Hadoop的partition和sort过程。如果partition和sort的key是不同的,可以使用 DISTRIBUTE BYSORT BY 分别指定。
  • MAP   和   REDUCE   关键字是   SELECT TRANSFORM 关键字的别名,原文中给出了上面等价代
    FROM (
    FROM pv_users
    MAP pv_users.userid, pv_users.date
    USING 'map_script'
    AS dt, uid
    CLUSTER BY dt
    ) map_output
    INSERT OVERWRITE TABLE pv_users_reduced
    REDUCE map_output.dt, map_output.uid
    USING 'reduce_script'
    AS date, count;

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多