分享

Hive 的扩展特性

pig2 2013-12-13 17:37:23 发表于 介绍解说 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 1 7689
Hive 是一个很开放的系统,很多内容都支持用户定制,包括:
  • 文件格式:Text File,Sequence File
  • 内存中的数据格式: Java Integer/String, Hadoop IntWritable/Text
  • 用户提供的 map/reduce 脚本:不管什么语言,利用 stdin/stdout 传输数据
  • 用户自定义函数: Substr, Trim, 1 – 1
  • 用户自定义聚合函数: Sum, Average…… n – 1
File Format
TextFileSequenceFIleRCFFile
Data typeText OnlyText/BinaryText/Binary
Internal Storage OrderRow-basedRow-basedColumn-based
CompressionFile BasedBlock BasedBlock Based
SplitableYESYESYES
Splitable After CompressionNoYESYES
CREATE TABLE mylog ( user_id BIGINT, page_url STRING, unix_time INT) STORED AS TEXTFILE;
当用户的数据文件格式不能被当前 Hive 所识别的时候,可以自定义文件格式。可以参考 contrib/src/java/org/apache/hadoop/hive/contrib/fileformat/base64 中的例子。写完自定义的格式后,在创建表的时候指定相应的文件格式就可以:
CREATE TABLE base64_test(col1 STRING, col2 STRING) STORED AS INPUTFORMAT 'org.apache.hadoop.hive.contrib. fileformat.base64.Base64TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.contrib. fileformat.base64.Base64TextOutputFormat';SerDe
SerDe 是 Serialize/Deserilize 的简称,目的是用于序列化和反序列化。序列化的格式包括:
  • 分隔符(tab、逗号、CTRL-A)
  • Thrift 协议
反序列化(内存内):
  • Java Integer/String/ArrayList/HashMap
  • Hadoop Writable 类
  • 用户自定义类

其中,LazyObject 只有在访问到列的时候才进行反序列化。 BinarySortable:保留了排序的二进制格式。
当存在以下情况时,可以考虑增加新的 SerDe:
  • 用户的数据有特殊的序列化格式,当前的 Hive 不支持,而用户又不想在将数据加载至 Hive 前转换数据格式。
  • 用户有更有效的序列化磁盘数据的方法。
用户如果想为 Text 数据增加自定义 Serde ,可以参照 contrib/src/java/org/apache/hadoop/hive/contrib/serde2/RegexSerDe.java 中的例子。RegexSerDe 利用用户提供的正则表倒是来反序列化数据,例如:
CREATE TABLE apache_log( host STRING, identity STRING, user STRING, time STRING, request STRING, status STRING, size STRING, referer STRING, agent STRING) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' WITH SERDEPROPERTIES ( "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|\\[[^\\]]*\\]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\"[^\"]*\") ([^ \"]*|\"[^\"]*\"))?", "output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s";) STORED AS TEXTFILE;
用户如果想为 Binary 数据增加自定义的 SerDE,可以参考例子:serde/src/java/org/apache/hadoop/hive/serde2/binarysortable,例如:
CREATE TABLE mythrift_table ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.thrift.ThriftSerDe' WITH SERDEPROPERTIES ( "serialization.class" = "com.facebook.serde.tprofiles.full", "serialization.format" = "com.facebook.thrift.protocol.TBinaryProtocol";);Map/Reduce 脚本(Transform)
用户可以自定义 Hive 使用的 Map/Reduce 脚本,比如:
FROM ( SELECT TRANSFORM(user_id, page_url, unix_time) USING 'page_url_to_id.py' AS (user_id, page_id, unix_time) FROM mylog DISTRIBUTE BY user_id SORT BY user_id, unix_time) mylog2 SELECT TRANSFORM(user_id, page_id, unix_time) USING 'my_python_session_cutter.py' AS (user_id, session_info);
Map/Reduce 脚本通过 stdin/stdout 进行数据的读写,调试信息输出到 stderr。
UDF(User-Defined-Function)
用户可以自定义函数对数据进行处理,例如:
add jar build/ql/test/test-udfs.jar; CREATE TEMPORARY FUNCTION testlength AS 'org.apache.hadoop.hive.ql.udf.UDFTestLength';   SELECT testlength(src.value) FROM src;   DROP TEMPORARY FUNCTION testlength;
UDFTestLength.java 为:
package org.apache.hadoop.hive.ql.udf;   public class UDFTestLength extends UDF { public Integer evaluate(String s) { if (s == null) { return null; } return s.length(); } }
自定义函数可以重载:
add jar build/contrib/hive_contrib.jar; CREATE TEMPORARY FUNCTION example_add AS 'org.apache.hadoop.hive.contrib.udf.example.UDFExampleAdd';   SELECT example_add(1, 2) FROM src; SELECT example_add(1.1, 2.2) FROM src;
UDFExampleAdd.java:
public class UDFExampleAdd extends UDF { public Integer evaluate(Integer a, Integer b) { if (a = null || b = null) return null; return a + b; }   public Double evaluate(Double a, Double b) { if (a = null || b = null) return null; return a + b; } }
%%
在使用 UDF 的时候,会自动进行类型转换,这个 java 或者 C 中的类型转换有些类似,比如:
SELECT example_add(1, 2.1) FROM src;
的结果是 3.1,这是因为 UDF 将类型为 Int 的参数 “1″ 转换为 double。
类型的隐式转换是通过 UDFResolver 来进行控制的,并且可以根据不同的 UDF 进行不同的控制。
UDF 还可以支持变长的参数,例如 UDFExampleAdd.java:
public class UDFExampleAdd extends UDF { public Integer evaluate(Integer... a) { int total = 0; for (int i=0; i<a.length; i++) if (a != null) total += a;   return total; } // the same for Double public Double evaluate(Double... a) }
使用例子为:
SELECT example_add(1, 2) FROM src; SELECT example_add(1, 2, 3) FROM src; SELECT example_add(1, 2, 3, 4.1) FROM src;
综上,UDF 具有以下特性:
  • 用 java 写 UDF 很容易。
  • Hadoop 的 Writables/Text 具有较高性能。
  • UDF 可以被重载。
  • Hive 支持隐式类型转换。
  • UDF 支持变长的参数。
  • genericUDF 提供了较好的性能(避免了反射)。
UDAF(User-Defined Aggregation Funcation)
例子:
SELECT page_url, count(1), count(DISTINCT user_id) FROM mylog;
UDAFCount.java:
public class UDAFCount extends UDAF { public static class Evaluator implements UDAFEvaluator { private int mCount;   public void init() { mcount = 0; }   public boolean iterate(Object o) { if (o!=null) mCount++;   return true; }   public Integer terminatePartial() { return mCount; }   public boolean merge(Integer o) { mCount += o; return true; }   public Integer terminate() { return mCount; } }

已有(2)人评论

跳转到指定楼层
yuwenge 发表于 2013-12-13 17:44:25
本帖最后由 yuwenge 于 2013-12-13 17:51 编辑

这里给大家补充一下

首先来看一下数据:

  1. hive> select * from test;
  2. OK
  3. 1       3
  4. 2       2
  5. 3       1
复制代码

假设,我们要输出每一列的md5值。在目前的hive中是没有这个udf的。

我们看一下Python的代码:

  1. #!/home/tops/bin/python
  2. import sys
  3. import hashlib
  4. for line in sys.stdin:
  5.     line = line.strip()
  6.     arr = line.split()
  7.     md5_arr = []
  8.     for a in arr:
  9.         md5_arr.append(hashlib.md5(a).hexdigest())
  10.     print "\t".join(md5_arr)
复制代码
在Hive中,使用脚本,首先要将他们加入:
  1. add file /xxxx/test.py
复制代码
然后,在调用时,使用TRANSFORM语法。
  1. SELECT
  2.     TRANSFORM (col1, col2)
  3.     USING './test.py'
  4.     AS (new1, new2)
  5. FORM
  6.     test;
复制代码

这里,我们使用了AS,指定输出的若干个列,分别对应到哪个列名。如果省略这句,则Hive会将第1个tab前的结果作为key,后面其余作为value。

这里有一个小坑:有时候,我们结合INSERT OVERWRITE使用上述TRANSFORM,而目标表,其分割副可能不是\t。但是请牢记:TRANSFORM的分割符号,传入、传出脚本的,永远是\t。不要考虑外面其他的分割符号!

最后,解释一下MAP、REDUCE。

在有的Hive语句中,大家可能会看到SELECT MAP (…)  USING ‘xx.py’这样的语法。

然而,在Hive中,MAP、REDUCE只不过是TRANSFORM的别名,Hive不保证一定会在map/reduce中调用脚本。

所以、混用map reduce语法关键字,甚至会引起混淆,所以建议大家还是都用TRANSFORM吧。

回复

使用道具 举报

zhangcd123 发表于 2013-12-13 18:02:53
不错,顶一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条