Cloudera Impala 支持数据文件使用 Avro 文件格式的表。Impala 能够查询 Avro 表,但目前不支持建立和插入数据。对于这些操做,使用 Hive 处理,而后切换回 Impala 执行查询。 html
继续阅读: node
请在 Hive 中使用包含 STORED AS AVRO 子句的 CREATE TABLE 语句来建立使用 Avro 文件格式的新表。关于经过 Hive 向 Avro 表加载数据的信息,参见 Avro page on the Hive wiki。 shell
当在 Hive 中建立了表以后,切换回 impala-shell 并执行 INVALIDATE METADATA 语句。而后你能够经过 impala-shell 查询这个表。 数据库
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 名,都被忽略。 apache
当你经过 Hive 建立了 Avro 表以后,只要它只使用 Impala 兼容的数据类型,你就能够在 Impala 中使用它(例如,它不能包含嵌套类型如 array, map, struct)。由于 Impala 和 Hive 共用相同的元数据数据库,Impala 能够直接访问 Hive 中建立的表的定义和表的数据。 json
当你在 Hive 中建立了 Avro 表以后,经过 impala-shell 在下次链接到 Impala 后执行 INVALIDATE METADATA。这是一次性操做,让 Impala 发现新表。假如你经过多个节点执行查询,在 Hive 建立新表以后,第一次链接到各个节点上时,在每个节点上执行 INVALIDATE METADATA 语句。 app
当你经过 Hive LOAD DATA 或 INSERT 语句,或者经过手工复制或移动文件到表对应的数据目录,这样加载新数据文件到 Avro 表以后,经过 impala-shell 在下次链接到 Impala 后执行 REFRESH table_name 语句。假如你经过多个节点执行查询,在 Impala 以外加载新数据以后,第一次链接到各个节点上时,在每个节点上执行 REFRESH 语句。 oop
Impala 仅支持 boolean, int, long, float, double, string 类型, 或这些类型与 null 值的联合; 例如,["string", "null"]。与 null 的联合本质上是建立一个可为 null 的类型。 fetch
如上所示,你能够直接在你的 CREATE TABLE 语句中嵌入模式(schema),在 Hive metastore 中列宽的约束限制了你能够设置的模式的长度(column width restrictions in the Hive metastore limit the length of schema you can specify)。假如你遇到长模式文字的问题,请尝试存储你的模式为一个 HDFS 中的 JSON 文件。使用相似下面的属性,设置你的 HDFS 中的模式: url
tblproperties ('avro.schema.url'='hdfs//your-name-node:port/path/to/schema.json');
为了给 Avro 表启用压缩,请在 Hive shell 中指定设置启用压缩,并设置编解码器,而后像以前的例子那样执行 CREATE TABLE 语句。Impala Avro 表支持 snappy 和 deflate 编解码器。
例如:
hive> set hive.exec.compress.output=true; hive> set avro.output.codec=snappy;
自 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