Hive的 TRANSFORM 关键字提供了在SQL中调用自写脚本的功能,适合实现Hive中没有的功能又不想写UDF的情况。例如,按日期统计每天出现的 uid 数,通常用如下的SQL
SELECT date, count(uid) FROM xxx GROUP BY date
但是,如果我想在reduce阶段对每天的 uid 形成一个列表,进行排序并输出,这在Hive中没有现成的功能。那么,可以自写脚本实现该功能,并用 TRANSFORM 关键字调用
SELECT TRANSFORM(date, uid) FROM xxx CLUSTER BY date
这是一个类似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的输入字段为 dt 和 uid ,输出处理后的前两个字段,并命名为 date , count ,写入到 pv_users_reduced 表中。
这里有几个细节:
mapper和reducer用到的script可以是任何可执行文件。 注意 如果用到的是本地文件,应当在语句开始前用 ADD FILE 或 ADD 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 BY 和 SORT BY 的简写,这两者可以认为对应与Hadoop的partition和sort过程。如果partition和sort的key是不同的,可以使用 DISTRIBUTE BY 和 SORT 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;
因此,原文中特别提醒, MAP 并没有强制产生一个map过程的作用, REDUCE 同理。只是为了阅读更清晰。
原文来源:https://m.pythontab.com/article/1119
共同学习,写下你的评论
评论加载中...
作者其他优质文章