原标题:马克斯Compute重装上战地 第五弹 – SELECT TRANSFO昂科雷

UDTF

  • Hive中UDTF编写和行使

摘要:
马克斯Compute(原ODPS卡塔 尔(阿拉伯语:قطر‎是Ali云自己作主研究开发的保有产业界抢先水平的遍布式大额管理平台,
特别在集团内部获得普遍应用,支撑了多个BU的主干业务。
马克斯Compute除了不停优化品质外,也从事于提高SQL语言的客户体验和表明技术,进步大范围ODPS开采者的坐褥力。

UDAF

  • Hive
    udaf开拓入门和平运动转进程详明
  • Hive通用型自定义聚合函数(UDAF卡塔尔

马克斯Compute(原ODPS卡塔 尔(英语:State of Qatar)是阿里云自己作主研究开发的富有产业界超过水平的布满式大数目处理平台,
特别在公司内部获得普及应用,支撑了多少个BU的主干职业。
马克斯Compute除了无休止优化质量外,也从事于升高SQL语言的客商体验和表明技艺,进步大规模ODPS开荒者的临盆力。

Hive中的TRANSFORM:使用脚本完结Map/Reduce

转自:
http://www.coder4.com/archives/4052

先是来看一下数量:

hive> select * from test;
OK
1       3
2       2
3       1

后生可畏经,大家要出口每一列的md5值。在当前的hive中是从未那么些udf的。

咱俩看一下Python的代码:

#!/home/tops/bin/python

import sys
import hashlib

for line in sys.stdin:
    line = line.strip()
    arr = line.split()
    md5_arr = []
    for a in arr:
        md5_arr.append(hashlib.md5(a).hexdigest())
    print "t".join(md5_arr)

在Hive中,使用脚本,首先要将她们参预:

add file /xxxx/test.py

然后,在调用时,使用TRANSFORM语法。

SELECT 
    TRANSFORM (col1, col2) 
    USING './test.py' 
    AS (new1, new2) 
FORM 
    test;

那边,大家接受了AS,钦命输出的若干个列,分别对应到哪个列名。假诺省略那句,则Hive会将第二个tab前的结果作为key,前面其他作为value。

那边有三个小坑:有的时候候,大家结合INSERT
OVE福睿斯WLX570ITE使用上述TRANSFORM,而指标表,其分割副大概不是t。可是请记住:TRANSFORM的剪切符号,传入、传出脚本的,长久是t。不要思考外面别的的剪切符号!

提起底,解释一下MAP、REDUCE。

在大器晚成部分Hive语句中,大家兴许会看见SELECT MAP (…) USING ‘xx.py’那样的语法。

可是,在Hive中,MAP、REDUCE只可是是TRANSFORM的别称,Hive不保证一定会在map/reduce中调用脚本。看看官方文书档案是怎么说的:

Formally, MAP ... and REDUCE ... are syntactic transformations of SELECT TRANSFORM ( ... ). In other words, they serve as comments or notes to the reader of the query. BEWARE: Use of these keywords may be dangerous as (e.g.) typing "REDUCE" does not force a reduce phase to occur and typing "MAP" does not force a new map phase!

为此、混用map
reduce语法关键字,以致会引起混淆,所以提出大家依然都用TRANSFORM吧。

友谊提示:如若脚本不是Python,而是awk、sed等体系内置命令,能够直接使用,而不用add
file。

假若表中有MAP,AEvoqueRAY等复杂类型,怎么用TRANSFORM生成?

例如:

CREATE TABLE features
(
    id BIGINT,
    norm_features MAP<STRING, FLOAT> 
);

答案是,要在剧本的输出中,对特别字段依据HDFS文件中的格式输出即可。

举例,以地点的表结构为例,每行输出应该为:

1^Ifeature1^C1.0^Bfeature2^C2.0

其中I是tab键,这是TRANSFORM要求的分割符号。B和^C是Hive存储时MAP类型的KV分割符。

别的,在Hive的TRANSFORM语句的时候,要留心AS中加上项目注明:

SELECT TRANSFORM(stuff)
USING 'script'
AS (thing1 INT, thing2 MAP<STRING, FLOAT>)

马克斯Compute基于ODPS2.0新一代的SQL引擎,显明升级了SQL语言编写翻译进程的易用性与语言的表明手艺。大家在这推出马克斯Compute(ODPS2.0)重装上沙场类别作品

Hive中的TRANSFORM:自定义Mapper和Reducer完成Map/Reduce

/**
 * Mapper.
 */
public interface Mapper {
  /**
   * Maps a single row into an intermediate rows.
   * 
   * @param record
   *          input record
   * @param output
   *          collect mapped rows.
   * @throws Exception
   *           on error
   */
  void map(String[] record, Output output) throws Exception;
}

能够将一列拆分为多列

选取样例:

public class ExecuteMap {

    private static final String FULL_PATH_CLASS = "com.***.dpop.ods.mr.impl.";

    private static final Map<String, Mapper> mappers = new HashMap<String, Mapper>();

    public static void main(String[] args) throws Exception {
        if (args.length < 1) {
            throw new Exception("Process class must be given");
        }

        new GenericMR().map(System.in, System.out,
                getMapper(args[0], Arrays.copyOfRange(args, 1, args.length)));
    }

    private static Mapper getMapper(String parserClass, String[] args)
            throws ClassNotFoundException {
        if (mappers.containsKey(parserClass)) {
            return mappers.get(parserClass);
        }

        Class[] classes = new Class[args.length];
        for (int i = 0; i < classes.length; ++i) {
            classes[i] = String.class;
        }
        try {
            Mapper mapper = (Mapper) Class.forName(FULL_PATH_CLASS + parserClass).getConstructor(classes).newInstance(args);
            mappers.put(parserClass, mapper);
            return mapper;
        } catch (ClassNotFoundException e) {
            throw new ClassNotFoundException("Unknown MapperClass:" + parserClass, e);
        } catch (Exception e) {
            throw new  ClassNotFoundException("Error Constructing processor", e);
        }

    }
}

MR_USING=" USING 'java -Xmx512m -Xms512m -cp ods-mr-1.0.jar:hive-contrib-2.3.33.jar com.***.dpop.ods.mr.api.ExecuteMap "

COMMAND="FROM dw_rtb.event_fact_adx_auction "
COMMAND="${COMMAND} INSERT overwrite TABLE dw_rtb.event_fact_mid_adx_auction_ad PARTITION(yymmdd=${CURRENT_DATE}) SELECT transform(search_id, print_time, pthread_id, ad_s) ${MR_USING} EventFactMidAdxAuctionAdMapper' as search_id, print_time, pthread_id, ad_s, ssp_id WHERE $INSERT_PARTITION and original = 'exinternal' "

率先弹 – 善用马克斯Compute编写翻译器的乖谬和警告

Hive Python Streaming的准绳及写法

http://www.tuicool.com/articles/vmumUjA

第二弹 – 新的着力数据类型与内建函数

其三弹 – 复杂类型

第四弹 – CTE,VALUES,SEMIJOIN

上次向你介绍了CTE,VALUES,SEMIJOIN,本篇向您介绍马克斯Compute对其余脚本语言的支撑

  • SELECT TRANSFORM。

  • 场景1

  • 自家的系统要动员搬迁到马克斯Compute平台上,系统中本来有大多成效是接受脚本来完结的,满含python,shell,ruby等剧本。
    要迁移到马克斯Compute上,作者急需把这个本子全体都改进成UDF/UDAF/UDTF。改造进程不止须求消耗费时间间人力,还亟需做贰回又一回的测量试验,从而确定保证改动成的udf和原先的本子在逻辑上是等价的。作者梦想能有更简便易行的迁徙格局。
  • 场景2
  • SQL相比较长于的是集聚操作,而自己索要做的专业要对一条数据做越来越多的精细的考虑,现成的放到函数不可能方便的落实自己想要的作用,而UDF的框架缺乏利索,並且Java/Python小编都不太了然。比较之下作者更专长写剧本。笔者就愿意能够写八个本子,数据全都输入到自身的脚本里来,我自个儿来做种种总括,然后把结果输出。而马克斯Compute平台就担负帮自身把数量做好切分,让自家的台本能够遍布式推行,担任数据的输入表和输出表的管住,肩负JOIN,UNION等关乎操作就好了。

上述功效可以使用SELECT TRANSFORM来促成

SELECT TRANSFORM 介绍

此文中运用马克斯Compute Studio作显示,首先,安装马克斯Compute
Studio,导入测量试验MaxCompute项目,创制工程,营造二个新的马克斯Compute脚本文件, 如下

云顶娱乐游戏平台官网 1

交给作业能够旁观举行布置(全体进展后的视图卡塔 尔(阿拉伯语:قطر‎:

云顶娱乐游戏平台官网 2

Select
transform允许sql客户钦定在服务器上实施一句shell命令,将中游数据各字段用tab分隔,每条记下黄金年代行,逐行输入shell命令的stdin,并从stdout读取数据作为出口,送到中游。Shell命令的实质是调用Unix的一些utility,由此得以运维别的的剧本解释器。富含python,java,php,awk,ruby等。

该命令宽容Hive的Transform功效,能够参照他事他说加以侦查Hive的文书档案。一些亟需小心的点如下:

  1. Using
    子句钦点的是要实践的指令,而非资源列表,那点和大相当多的马克斯Compute
    SQL语法不一样等,这么做是为了和hive的语法保持十二分。

  2. 输入从stdin传入,输出从stdout传出;

  3. 能够配备分隔符,暗中同意使用 t 分隔列,用换行分隔行;

  4. 可以自定义reader/writer,但用内置的reader/writer会快比比较多

  5. 采纳自定义的能源(脚本文件,数据文件等卡塔 尔(英语:State of Qatar),能够行使 set
    odps.sql.session.resources=foo.sh,bar.txt;
    来钦赐。能够内定七个resource文件,用逗号隔开分离(因而分化意resource名字中包涵逗号和分行卡塔尔国。别的大家还提供了resources子句,能够在using
    子句前面钦命 resources ‘foo.sh’, ‘bar.txt’
    来钦点能源,二种办法是等价的(参谋“用odps跑测量检验”的事例卡塔尔国;

6.
能源文件会被下载到推行钦赐命令的干活目录,能够使用文件接口展开./bar.txt文件。

现阶段odps select transform完全协作了hive的语法、功用和行事,富含input/output row format 以至reader/writer。Hive上的本子,半数以上方可一贯拿来运作,部分脚本只须求通过轻便改变就可以运维。其余我们广大要义都用比hive更加高推行功效的语言
(C++) 重构,用以优化质量。

选用项景比方

答辩上select transform能促成的效能udtf都能完成,可是select
transform比udtf要灵活得多。且select
transform不止扶助java和python,还扶植shell,perl等任何脚本和工具。
且编写的进程要简明,特别相符adhoc功能的落到实处。举几个例子:

  1. 兴风作浪造数据

云顶娱乐游戏平台官网 3

抑或应用python

云顶娱乐游戏平台官网 4

地点的语句造出意气风发份有50行的数据表,值是从1到50;
测量试验时候的多寡就足以方便造出来了。功效相近简单,但此前是odps的多少个痛点,未有有利的措施造数据,就不便于测验以致初读书人的上学和研究。当然那也得以通过udtf来贯彻,不过急需复杂的流程:步向ide->写udtf->打包->add
jar/python->create function->试行->drop function->drop
resource。

  1. awk 客商会很喜欢那么些职能

云顶娱乐游戏平台官网 5

地方的语句仅仅是把value原样输出,可是熟谙awk的顾客,自此过上了写awk脚本不写sql的生活

  1. 用odps跑测试

云顶娱乐游戏平台官网 6

或者

云顶娱乐游戏平台官网 7

以那一件事例是为着说明,相当多java的utility能够一向拿来运作。java和python固然有现存的udtf框架,不过用select
transform编写更简约,并且不必要拾分正视,也还没格式供给,以致可以达成离线脚本拿来平昔就用。

  1. 扶植任何脚本语言

select transform (key, value) using “perl -e ‘while($input =
<STDIN>){print $input;}'” from src;

上边用的是perl。那实质上不单是言语协助的恢宏,一些粗略的效果,awk,
python, perl, shell
都扶助间接在指令里面写剧本,无需写脚本文件,上传财富等进度,开拓进度更简便易行。此外,由于当下大家总计集群上尚无php和ruby,所以那二种脚本不扶植。

  1. 能够串联着用,使用 distribute by和 sort by对输入数据做预管理

云顶娱乐游戏平台官网 8

要么用map,reduce的显要字会让逻辑显得清楚部分

云顶娱乐游戏平台官网 9

理论上OpenM本田UR-V的模子都能够映射到上面的测算进度。注意,使用map,reduce,select
transform那多少个语法其实语义是均等的,用哪个关键字,哪一类写法,不影响一向进程和结果。

性能

天性上,SELECT TRANSFORM 与UDTF
齐头并进。经过各类场直面比测量检验,数据量超级小时,大许多场景下select
transform有优势,而数据量大时UDTF有优势。由于transform的开垦特别便民,所以select
transform特别符合做adhoc的多少解析。

UDTF的优势:

  1. UDTF是有项目,而Transform的子进度基于stdin/stdout传输数据,全体数据都用作string管理,因而transform多了一步类型转变;
  2. Transform数据传输信任于操作系统的管道,而当前管道的buffer唯有4KB,且无法设置,
    transform读/写 空/满 的pipe会引致进度被挂起;
  3. UDTF的常量参数能够不用传输,而Transform无法利用那么些优化。

SELECT TRANSFORM 的优势:

  1. 子进度和父进度是八个进度,而UDTF是单线程的,假使总计占比比较高,数据吞吐量非常小,能够利用服务器的多核性情
  2. 数码的传导通过更底层的系统调用来读写,效用比java高
  3. SELECT
    TRANSFORM辅助的一些工具,如awk,是natvie代码达成的,和java相比较理论上大概会有总体性优势。

小结

马克斯Compute基于ODPS2.0的SQL引擎,提供了SELECT
TRANSFORM作用,能够分明简化对台本代码的引用,与此同一时候,也抓牢了质量!我们推荐你尽可能接受SELECT
TRANSFORM。

标注

  • 注大器晚成,USING
    前面包车型客车字符串,在后台是从来起的子进度来调起命令,未有起shell,所以shell的一些语法,如输入输出重定向,管道等是不援救的。假若客商须要能够以
    shell 作为命令,真正的一声令下作为数据输入,参谋“推波助澜造数据”的例证;
  • 注二,JAVA 和 PYTHON 的其实路线,可以从JAVA_HOME 和 PYTHON_HOME
    情况变量中得到作业;

作者:隐林

本文为云栖社区原创内容,未经允许不得转发。回去知乎,查看越来越多

主编:

相关文章