Hive官方使用手册——Avro Files

本文为自己翻译的译文,原文地址:https://cwiki.apache.org/confluence/display/Hive/AvroSerDe


Availability

最早支持AvroSerDe的版本

The AvroSerde is available in Hive 0.9.1 and greater.

概述 –  Hive中使用Avro

AvroSerde允许用户读取或写入Avro数据到Hive表。以下是AvroSerde的注意事项:

  • 从Avro schema中推断出Hive表的schema。从Hive 0.14开始,可以从Hive表的schema推断Avro模式
  • 利用Avro的向后兼容性能力,在一个表中以指定的模式读取所有Avro文件。
  • 支持任意嵌套模式。
  • 将所有Avro数据类型转换为等效的Hive类型。 大多数类型都可以匹配,但是一些Avro类型不存在于Hive中,AvroSerDe会自动转换。
  • 能够解析压缩后的Avro文件。
  • 显式地将可空类型的Avro处理习惯用法Union[T, null] 转换为只有T,并在适时返回null。
  • 将任何Hive表写入Avro文件。
  • 对于ETL过程的工作,Avro模式依然表现的非常可靠。
  • 从Hive 0.14开始,可以使用Alter table语句将列添加到Avro支持的Hive表中。

有关SerDes的一般信息,请参阅开发指南中的Hive SerDe。还请参阅SerDe,了解输入和输出处理的详细信息。

Requirements

The AvroSerde has been built and tested against Hive 0.9.1 and later, and uses Avro 1.7.5 as of Hive 0.13 and 0.14.

Hive Versions
Avro Version
Hive 0.9.1 Avro 1.5.3
Hive 0.10, 0.11, and 0.12 Avro 1.7.1
Hive 0.13 and 0.14 Avro 1.7.5

Avro to Hive type conversion

While most Avro types convert directly to equivalent Hive types, there are some which do not exist in Hive and are converted to reasonable equivalents. Also, the AvroSerde special cases unions of null and another type, as described below:

Avro type                                                                                

Becomes Hive type                                                                                                                                        

Note                                             

null

void

boolean

boolean

int

int

long

bigint

float

float

double

double

bytes

binary

在Hive 0.12.0之前,bytes被转换为数组[smallint]。

string

string

record

struct

map

map

list

array

union

union

[T, null]的联合显式地转换可为空的T,其他类型直接转换为Hive的类型结合。然而,在Hive 7中引入了union,目前还不能在where/group-by语句中使用。从本质上说,他们只是能够看到。因为AvroSerde显式地将[T,null]转换为nullable T,这个限制只适用于多个类型联合或组合的联合,而不是单个类型和null。

enum

string

Hive没有enums的概念。

fixed

binary

Fixeds在Hive 0.12.0之前被转换成数组[smallint]。

创建Avro-backed Hive表

使用AvroSerDe可以在Hive中创建avro支持的表。

All Hive versions

创建Avro-backed表,使用org.apache.hadoop.hive.serde2.avro.AvroSerDe指定serde ,指定输入格式为org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat和输出格式为org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat。还提供了一个位置,AvroSerde将从该位置提取大部分表的当前模式。例如:

CREATE TABLE kst
   PARTITIONED BY (ds string)
   ROW FORMAT SERDE
   'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
   STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
   OUTPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
   TBLPROPERTIES (
     'avro.schema.url' = 'http://schema_provider/kst.avsc' );

在这个示例中,我们从一个webserver中提取了“真相”阅读器模式。下面描述了提供这个模式的其他参数。

Avro文件添加到数据库(或者创建一个外部表)使用标准的Hive操作(http://wiki.apache.org/hadoop/Hive/LanguageManual/DML)。

此表的描述如下:

hive> describe kst;
OK
string1 string  from deserializer
string2 string  from deserializer
int1     int      from deserializer
boolean1         boolean  from deserializer
long1   bigint  from deserializer
float1   float    from deserializer
double1  double   from deserializer
inner_record1   struct<int_in_inner_record1: int ,string_in_inner_record1:string> from deserializer
enum1   string  from deserializer
array1  array<string>   from deserializer
map1    map<string,string>      from deserializer
union1  uniontype< float , boolean ,string> from deserializer
fixed1  binary  from deserializer
null1    void     from deserializer
unionnullint     int      from deserializer
bytes1  binary  from deserializer

在这一点上,avo支持的表可以像任何其他表一样在Hive中工作。

Hive 0.14及以后的版本

从Hive 0.14开始,可以通过在DDL语句中使用“STORED AS AVRO”来创建AVRO支持的表。AvroSerDe负责从Hive表模式中创建合适的Avro模式,这在Hive的Avro可用性方面取得了很大的成功。

例如:

CREATE TABLE kst (
     string1 string,
     string2 string,
     int1  int ,
     boolean1  boolean ,
     long1 bigint,
     float1  float ,
     double1  double ,
     inner_record1 struct<int_in_inner_record1: int ,string_in_inner_record1:string>,
     enum1 string,
     array1 array<string>,
     map1 map<string,string>,
     union1 uniontype< float , boolean ,string>,
     fixed1 binary,
     null1  void ,
     unionnullint  int ,
     bytes1 binary)
   PARTITIONED BY (ds string)
   STORED AS AVRO;

这个表的描述如下:

hive> describe kst;
OK
string1 string  from deserializer
string2 string  from deserializer
int1     int      from deserializer
boolean1         boolean  from deserializer
long1   bigint  from deserializer
float1   float    from deserializer
double1  double   from deserializer
inner_record1   struct<int_in_inner_record1: int ,string_in_inner_record1:string> from deserializer
enum1   string  from deserializer
array1  array<string>   from deserializer
map1    map<string,string>      from deserializer
union1  uniontype< float , boolean ,string> from deserializer
fixed1  binary  from deserializer
null1    void     from deserializer
unionnullint     int      from deserializer
bytes1  binary  from deserializer

把表格写入Avro文件

AvroSerde可以将任何Hive表序列化为Avro文件。这使得它可以高效的转换任意Hive类型为Avro格式文件。为了将一个表写入Avro文件,您首先必须创建一个适当的Avro Schema(除了Hive 0.14.0及后续版本,如下面所述)。创建使用select语法语句当前不受支持。

类型转换如表中所示。对于不直接翻译的类型,有几项需要记住:

  • 可能为空的类型必须定义为该类型的联合,并且在Avro中为null。 未定义的字段中的null将导致保存期间的异常。不需要对Hive模式进行更改来支持这一点,因为Hive中的所有字段都可以是null。
  • Avro字节类型应该在Hive中定义为小的ints列表。AvroSerde在保存过程中会将这些转换成字节。
  • Avro Fixed类型应该在Hive中定义为小的ints列表。在保存过程中,AvroSerde会将它们转换为固定的。
  • Avro Enum类型应该在Hive中定义为字符串,因为Hive没有enums的概念。确保在表中只存在有效的枚举值,否则尝试保存非定义的枚举将导致异常。

Hive对于类型非常宽容:它将尝试在新表的等价列中存储与所提供的列匹配的任何值。例如,没有对列名进行匹配。因此,在查询编写器中,必须确保目标列类型是正确的。如果不是,Avro可以接受该类型,否则可能会抛出异常:这取决于特定类型的组合。

样例

查看下面的Hive表,它涵盖了所有类型的Hive数据类型,使它成为一个很好的例子::

CREATE TABLE test_serializer(string1 STRING,
                              int1 INT,
                              tinyint1 TINYINT,
                              smallint1 SMALLINT,
                              bigint1 BIGINT,
                              boolean1 BOOLEAN,
                              float1 FLOAT,
                              double1 DOUBLE,
                              list1 ARRAY<STRING>,
                              map1 MAP<STRING,INT>,
                              struct1 STRUCT<sint:INT,sboolean:BOOLEAN,sstring:STRING>,
                              union1 uniontype<FLOAT, BOOLEAN, STRING>,
                              enum1 STRING,
                              nullableint INT,
                              bytes1 BINARY,
                              fixed1 BINARY)
  ROW FORMAT DELIMITED FIELDS TERMINATED BY  ','  COLLECTION ITEMS TERMINATED BY  ':'  MAP KEYS TERMINATED BY  '#'  LINES TERMINATED BY  '\n'
  STORED AS TEXTFILE;

如果表是由csv文件支持的,例如:

why hello there

42

3

100

1412341

true

42.43

85.23423424

alpha:beta:gamma

Earth#42:Control#86:Bob#31

17:true:Abe Linkedin

0:3.141459

BLUE

72

^A^B^C

^A^B^C

another record

98

4

101

9999999

false

99.89

0.00000009

beta

Earth#101

1134:false:wazzup

1:true

RED

NULL

^D^E^F^G

^D^E^F

third record

45

5

102

999999999

true

89.99

0.00000000000009

alpha:gamma

Earth#237:Bob#723

102:false:BNL

2:Time to go home

GREEN

NULL

^H

^G^H^I

然后你可以把它写成下面描述的Avro。

All Hive versions

为了将这个表保存为Avro文件,创建一个等效的Avro模式(记录的名称空间和实际名称不重要):

{
   "namespace" "com.linkedin.haivvreo" ,
   "name" "test_serializer" ,
   "type" "record" ,
   "fields" : [
     "name" : "string1" "type" : "string"  },
     "name" : "int1" "type" : "int"  },
     "name" : "tinyint1" "type" : "int"  },
     "name" : "smallint1" "type" : "int"  },
     "name" : "bigint1" "type" : "long"  },
     "name" : "boolean1" "type" : "boolean"  },
     "name" : "float1" "type" : "float"  },
     "name" : "double1" "type" : "double"  },
     "name" : "list1" "type" :{ "type" : "array" "items" : "string" } },
     "name" : "map1" "type" :{ "type" : "map" "values" : "int" } },
     "name" : "struct1" "type" :{ "type" : "record" "name" : "struct1_name" "fields" : [
           "name" : "sInt" "type" : "int"  }, {  "name" : "sBoolean" "type" : "boolean"  }, {  "name" : "sString" "type" : "string"  } ] } },
     "name" : "union1" "type" :[ "float" "boolean" "string" ] },
     "name" : "enum1" "type" :{ "type" : "enum" "name" : "enum1_values" "symbols" :[ "BLUE" , "RED" "GREEN" ]} },
     "name" : "nullableint" "type" :[ "int" "null" ] },
     "name" : "bytes1" "type" : "bytes"  },
     "name" : "fixed1" "type" :{ "type" : "fixed" "name" : "threebytes" "size" : 3 } }
   ] }

然后你可以把它写到Avro文件:

CREATE TABLE as_avro
   ROW FORMAT SERDE
   'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
   STORED as INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
   OUTPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
   TBLPROPERTIES (
     'avro.schema.url' = 'file:///path/to/the/schema/test_serializer.avsc' );
 
INSERT OVERWRITE TABLE as_avro SELECT * FROM test_serializer;

Hive 0.14 and later

在Hive版本0.14和之后,您不需要手动创建Avro模式。上面所示的程序将一个表保存为Avro文件,减少到一个DDL语句,然后插入到表中。

CREATE TABLE as_avro(string1 STRING,
                      int1 INT,
                      tinyint1 TINYINT,
                      smallint1 SMALLINT,
                      bigint1 BIGINT,
                      boolean1 BOOLEAN,
                      float1 FLOAT,
                      double1 DOUBLE,
                      list1 ARRAY<STRING>,
                      map1 MAP<STRING,INT>,
                      struct1 STRUCT<sint:INT,sboolean:BOOLEAN,sstring:STRING>,
                      union1 uniontype<FLOAT, BOOLEAN, STRING>,
                      enum1 STRING,
                      nullableint INT,
                      bytes1 BINARY,
                      fixed1 BINARY)
STORED AS AVRO;
INSERT OVERWRITE TABLE as_avro SELECT * FROM test_serializer;

Avro file 扩展

虽然由Hive作业编写的文件是有效的Avro文件,然而,MapReduce并没有添加标准的. avro扩展。如果您将这些文件复制出来,您可能要用.avro重命名它们。

指定表的Avro模式

有三种方法可以为Avro表提供读者模式,所有这些方法都涉及到serde的参数。随着模式的发展,您可以通过更新表中的参数来更新这些值。

Use avro.schema.url

指定访问模式的URL。对于http模式,这适用于测试和小规模集群,但由于在作业中每个任务中至少会访问一个模式,因此可以快速将工作转换为针对URL的DDOS攻击程序(例如,web服务器)。除了测试之外,使用此参数时要谨慎。

模式也可以指向HDFS上的一个位置,例如:hdfs://your-nn:9000/path/to/avsc/file。然后AvroSerde将读取来自HDFS的文件,该文件应该对许多读取同时提供弹性。请注意,serde将从每个mapper读取这个文件,因此一个好的方法是将模式文件的复制转换为高值为读取提供良好的位置。模式文件本身应该是相对较小的,因此这不会在过程中增加大量的开销。

Use schema.literal and embed the schema in the create statement

您可以将模式直接嵌入到create语句中。如果模式没有任何单引号(或者它们被适当地转义了),那么这就起作用了,因为Hive使用它来定义参数值。例如:

CREATE TABLE embedded
   COMMENT  "just drop the schema right into the HQL"
   ROW FORMAT SERDE
   'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
   STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
   OUTPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
   TBLPROPERTIES (
     'avro.schema.literal' ='{
       "namespace" "com.howdy" ,
       "name" "some_schema" ,
       "type" "record" ,
       "fields" : [ {  "name" : "string1" , "type" : "string" }]
     }');

注意,该值被括在单引号中并粘贴到create语句中。

Use avro.schema.literal and pass the schema into the script

Hive可以做简单的变量替换,您可以将嵌入在变量中的模式传递给脚本。注意,要做到这一点,模式必须完全转义(回车转换为\n,标签到\t,引号转义等)。一个例子:

set hiveconf:schema;
DROP TABLE example;
CREATE TABLE example
   ROW FORMAT SERDE
   'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
   STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
   OUTPUTFORMAT
   'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
   TBLPROPERTIES (
     'avro.schema.literal' = '${hiveconf:schema}' );

要执行这个脚本文件,假设$SCHEMA被定义为转义模式值:

hive --hiveconf schema= "${SCHEMA}"  -f your_script_file.sql

注意,$SCHEMA被插入到引号中,以正确处理模式中的空格。

使用none来忽略avro.schema.literal或avro.schema.url

Hive没有提供一个简单的方法来取消或删除一个属性。如果您希望从一种使用URL或模式切换到另一种,则将被忽略的值设置为none, AvroSerde将把它视为未设置。

HBase 整合

Hive 0.14.0支持在HBase列中存储和查询Avro对象,使其可视为Hive结构。这使得Hive能够对HBase数据进行特别的分析,这些数据可以被深度结构化。在0.14.0之前,HBase Hive集成只支持在列中查询原始数据类型。有关详细信息,请参阅存储在HBase列中的Avro数据

一旦出现问题

在工作提交之前,Hive倾向于从AvroSerde中接收异常。为了使Hive更加冗长,它可以用*hive --hiveconf hive.root.logger=INFO,console*启动,它将向控制台发送大量的信息,并且可能包含AvroSerde正在试图告诉你哪里出了问题的所有信息。如果AvroSerde在MapReduce期间遇到错误,将在失败的任务日志中提供堆栈跟踪,这可以从JobTracker的web界面进行检查 。AvroSerde只发出AvroSerdeException;请在所有的错误报告中包含这些内容。最常见的是在试图序列化与Avro所期望的不兼容类型时出现的异常。

FAQ

  • 当描述表或对表运行查询时的url时为什么会报错error-error-error-error-error-error-error和一个检查avro.schema.literal 和 avro.schema.url的消息。?

AvroSerde在查找或解析avro.schema提供的模式时返回此消息。文字或avro.avro.schema。url的值。它不能更具体,因为Hive期望所有调用serde配置方法都是成功的,这意味着我们不能返回一个实际的异常。通过这个消息发送一个错误,表被保存在一个良好的状态中,错误的值可以通过调用alter table T set TBLPROPERTIES来纠正。

 


猜你喜欢

转载自blog.csdn.net/maizi1045/article/details/79664527