Impala 表使用 Avro 文件格式(翻译)

Impala 表使用 Avro 文件格式

Cloudera Impala 支持数据文件使用 Avro 文件格式的表。Impala 可以查询 Avro 表,但目前不支持创建和插入数据。对于这些操作,使用 Hive 处理,然后切换回 Impala 执行查询。

继续阅读:

  • 创建 Avro 表
  • 在 Impala 中使用 Hive 创建的 Avro 表
  • 通过 JSON 设置 Avro 模式
  • Avro 表启用压缩
  • How Impala Handles Avro Schema Evolution

创建 Avro 表

请在 Hive 中使用包含 STORED AS AVRO 子句的 CREATE TABLE 语句来创建使用 Avro 文件格式的新表。关于通过 Hive 向 Avro 表加载数据的信息,参见 Avro page on the Hive wiki。

当在 Hive 中创建了表之后,切换回 impala-shell 并执行 INVALIDATE METADATA 语句。然后你可以通过 impala-shell 查询这个表。

下面的例子演示了如何在 Hive 中创建 Avro 表:
hive> CREATE TABLE new_table
    > 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'='{
    >    "name": "my_record",
    >    "type": "record",
    >    "fields": [
    >       {"name":"bool_col", "type":"boolean"},
    >       {"name":"int_col", "type":"int"},
    >       {"name":"long_col", "type":"long"},
    >       {"name":"float_col", "type":"float"},
    >       {"name":"double_col", "type":"double"},
    >       {"name":"string_col", "type":"string"},
    >       {"name": "nullable_int", "type": ["null", "int"]]}');
OK
Time taken: 6.372 seconds

Record 的每一个字段成为标准的列。注意任何其他的信息,如 record 名,都被忽略。

  Note: 对于允许为空的列,请确保在实际类型名之前加上 "null" 条目。


在 Impala 中使用 Hive 创建的 Avro 表


当你通过 Hive 创建了 Avro 表之后,只要它只使用 Impala 兼容的数据类型,你就可以在 Impala 中使用它(例如,它不能包含嵌套类型如 array, map, struct)。因为 Impala 和 Hive 共用相同的元数据数据库,Impala 可以直接访问 Hive 中创建的表的定义和表的数据。

当你在 Hive 中创建了 Avro 表之后,通过 impala-shell 在下次连接到 Impala 后执行 INVALIDATE METADATA。这是一次性操作,让 Impala 发现新表。假如你通过多个节点执行查询,在 Hive 创建新表之后,第一次连接到各个节点上时,在每一个节点上执行 INVALIDATE METADATA 语句。

当你通过 Hive LOAD DATA 或 INSERT 语句,或者通过手工复制或移动文件到表对应的数据目录,这样加载新数据文件到 Avro 表之后,通过 impala-shell 在下次连接到 Impala 后执行 REFRESH table_name 语句。假如你通过多个节点执行查询,在 Impala 之外加载新数据之后,第一次连接到各个节点上时,在每一个节点上执行 REFRESH 语句。

Impala 仅支持 boolean, int, long, float, double, string 类型, 或这些类型与 null 值的联合; 例如,["string", "null"]。与 null 的联合本质上是创建一个可为 null 的类型。




通过 JSON 设置 Avro 模式


如上所示,你可以直接在你的 CREATE TABLE 语句中嵌入模式(schema),在 Hive metastore 中列宽的约束限制了你可以设置的模式的长度(column width restrictions in the Hive metastore limit the length of schema you can specify)。假如你遇到长模式文字的问题,请尝试存储你的模式为一个 HDFS 中的 JSON 文件。使用类似下面的属性,设置你的 HDFS 中的模式

tblproperties ('avro.schema.url'='hdfs//your-name-node:port/path/to/schema.json');



Avro 表启用压缩

为了给 Avro 表启用压缩,请在 Hive shell 中指定设置启用压缩,并设置编解码器,然后像之前的例子那样执行 CREATE TABLE 语句。Impala Avro 表支持 snappy 和 deflate 编解码器。

例如:

hive> set hive.exec.compress.output=true;
hive> set avro.output.codec=snappy;

How Impala Handles Avro Schema Evolution


自 Impala 1.1 开始, Impala 可以处理采用模式演变(schema evolution) 的 Avro 数据文件,这些不同的数据文件在同一个表中,并使用略微不同的类型定义(你可以通过在 Hive shell中运行 ALTER TABLE 语句执行 schema evolution 操作)。所修改的列的旧的和新的类型必须是兼容的,例如一个列开始可能是 int 然后修改为 bigint/float。

当任意表的定义被修改,或在当前 impalad 节点之外添加数据,假如 Avro 模式通过 Hive 修改,请确保 Impala 加载了表的最新的元数据。执行 REFRESH table_name 或 INVALIDATE METADATA table_name 语句来加载。REFRESH 立即加载元数据,而 INVALIDATE METADATA 在下次表访问时加载元数据。

当查询不涉及到 Avro 数据文件或列时,Impala 不会检查它们的一致性。因此,假如你执行 SELECT c1, c2 FROM t1, 如果列 c3 以兼容的方式进行了修改,Impala 不会返回任何错误。假如查询只返回部分分区的数据,Impala 不会检查未使用分区的数据文件。

在 Hive DDL 语句中,你可以设置 avro.schema.literal 表属性(如果模式定义为short) or an avro.schema.url 属性(如果模式定义为 long,或允许方便的编辑定义)。

例如,在 Hive shell 中运行以下 SQL 代码创建一个使用 Avro 文件格式的表,并放入一些例子数据:

CREATE TABLE avro_table (a string, b 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.literal'='{
    "type": "record",
    "name": "my_record",
    "fields": [
      {"name": "a", "type": "int"},
      {"name": "b", "type": "string"}
    ]}');

INSERT OVERWRITE TABLE avro_table SELECT 1, "avro" FROM functional.alltypes LIMIT 1;

一当 Avro 表被创建并包含数据之后,你就可以通过 impala-shell 命令查询:

-- [localhost:21000] > select * from avro_table;
-- Query: select * from avro_table
-- Query finished, fetching results ...
-- +---+------+
-- | a | b    |
-- +---+------+
-- | 1 | avro |
-- +---+------+

现在在 Hive shell 中,你修改了一个列的类型,并添加一个包含默认值的新列:

-- Promote column "a" from INT to FLOAT (no need to update Avro schema)
ALTER TABLE avro_table CHANGE A A FLOAT;

-- Add column "c" with default
ALTER TABLE avro_table ADD COLUMNS (c int);
ALTER TABLE avro_table SET TBLPROPERTIES (
  'avro.schema.literal'='{
    "type": "record",
    "name": "my_record",
    "fields": [
      {"name": "a", "type": "int"},
      {"name": "b", "type": "string"},
      {"name": "c", "type": "int", "default": 10}
    ]}');

再次回到 impala-shell,你可以基于该表最新的模式定义查询这个表。因为表的元数据是在 Impala 之外修改的,应首先执行 REFRESH 语句一边 Impala 更新该表的元数据到最新。

-- [localhost:21000] > refresh avro_table;
-- Query: refresh avro_table
-- Query finished, fetching results ...

-- Returned 0 row(s) in 0.23s
-- [localhost:21000] > select * from avro_table;
-- Query: select * from avro_table
-- Query finished, fetching results ...
-- +---+------+----+
-- | a | b    | c  |
-- +---+------+----+
-- | 1 | avro | 10 |
-- +---+------+----+
-- Returned 1 row(s) in 0.14s


你可能感兴趣的:(Impala 表使用 Avro 文件格式(翻译))