Cloudera Impala 支持使用文本文件做为输入输出的存储格式。Text files are a convenient format to use for interchange with other applications or scripts that produce or read delimited text files, such as CSV or TSV with commas or tabs for delimiters. html
文本文件在列定义方面一样很是灵活。例如,文本文件中能够包含比 Impala 表中定义的更多的字段,在查询时这些额外的字段会被忽略掉;也能够包含比 Impala 表更少的字段,在查询时这些缺乏的字段被视为 NULL 值。你能够包含表中被视为数值或时间戳的字段,而后使用 ALTER TABLE ... REPLACE COLUMNS 来设置为字符串,或者相反。 sql
继续阅读: shell
数据存放成文本文件是至关笨重的,而且不如二进制格式如 Parquet 高效。一般在这些状况下才在 Imapla 中使用文本文件格式:接收到的是文本文件而且在这个流程中没法控制,或者你是 Hadoop 新手不熟悉产生其余格式文件的技术(由于 CREATE TABLE 的默认文件格式是文本,你可使用文本文件格式建立你的第一个表而无需过多考虑性能问题)。不要紧,找机会在更关注性能的查询中使用更高效的文件格式。 apache
对于频繁查询的数据,你应当把原始的文本文件加载到 Impala 表里,而后使用 INSERT 语句把数据传输到使用 Parquet 文件格式的其余表中;当数据被存放到目标表后,数据格式自动进行了转换。 ubuntu
对于更紧凑的数据,考虑使用 LZO 压缩的文本文件。 LZO 是 Impala 惟一支持的文本文件压缩编解码器,由于 LZO 数据文件的 "可分割(splittable)" 性使得不一样的节点能够并行处理相同文件的不一样部分。参见 Using LZO-Compressed Text Files 了解详细信息。 架构
建立一个使用文本数据文件的表: app
加入数据文件没有使用其余的格式(例如分隔符) ,使用后面不包括其余子句的 CREATE TABLE 语句建立一个文本文件格式的表。例如: 分布式
create table my_table(id int, s string, n int, t timestamp, b boolean);
INSERT 语句建立的数据文件将使用 Ctrl-A (十六进制的 01) 字符做为列的分隔符。 ide
常见的使用状况是把一个已有的文本文件导入 Impala 表中。语法更详细,后面包括几个子句;重要的是其中的 FIELDS TERMINATED BY 子句。例如: oop
create table csv(id int, s string, n int, t timestamp, b boolean) stored as textfile fields terminated by ','; create table tsv(id int, s string, n int, t timestamp, b boolean) stored as textfile fields terminated by '\t'; create table pipe_separated(id int, s string, n int, t timestamp, b boolean) stored as textfile fields terminated by '|';
你能够建立使用指定分隔符的表,来用格式熟悉的格式如 CSV, TSV, 数显分割(pipe-separated) 导入文本文件。你也可使用这些表生成数据数据文件,先经过 INSERT ... SELECT 语法把数据复制到 Impala 表里,而后导出这些表数据目录下的数据文件。
不要在你构建的文本数据文件中的值上包以引号。假如你须要在字段值里包含分隔符,例如把一个包含逗号的字符串值放入 CSV 格式的数据文件里,应在 CREATE TABLE 语句中使用 ESCAPED BY 子句设置转义字符, 并在须要转移的字符前加上转义符号。
执行 DESCRIBE FORMATTED table_name 语句来查看每个表在 Impala 内部表示的详细信息。
当 Impala 查询一个包含文本文件格式数据的表时,将查询这个表的数据目录下的全部数据文件。Impala 忽略全部的隐藏文件,也就是说,以 . 开头的全部文件名。另外,文件名是没有特定含义的(not significant)。
经过 Impala INSERT 语句产生的数据文件名被赋予惟一的文件名,以免文件名冲突。
INSERT ... SELECT 语句在每个处理 SELECT 部分的节点上产生一个数据文件。INSERT ... VALUES 语句为其中的每个语句产生一个单独的数据文件;由于 Impala 查询少许的巨大文件比查询大量的小文件更高效, 因此不推荐使用 INSERT ... VALUES 语法加载大量的数据。假如你发现你的表是由于包含太多小文件而低效,经过执行 INSERT ... SELECT 传输数据到新表,重组这些数据到少许的大文件中。
加载已有的文本文件到 Impala 文本文件表时,请使用 LOAD DATA 语句,并指定文件在 HDFS 中的路径。这些文件会移动到对应的 Impala 数据目录下。
加载已有的多个文本文件到 Impala 文本文件表时,请使用 LOAD DATA 语句,并指定包含这些文件的 HDFS 目录。全部非隐藏的文件都会移动到对应的 Impala 数据目录下。
请使用以下语句,将 Impala 支持的其余文件格式转换为文本格式:
INSERT INTO text_table SELECT column_list FROM other_file_format_table; -- 默认分隔符为十六进制的 01 CREATE TABLE text_table AS SELECT column_list FROM other_file_format_table; -- 为生成的 CSV,TSV 等文件设置分隔符 CREATE TABLE text_table AS SELECT column_list FROM other_file_format_table ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
这是一个颇有用的技术,能够查看 Impala 如何表示特殊值。
请使用 INSERT ... VALUES 语法,建立用于测试的包含少许数据的文本文件表:
INSERT INTO text_table VALUES ('string_literal',100,hex('hello world'));
当为 Impala 文本文件表建立文本文件时,请使用 \N 表示 NULL。关于 NULL 和空字符串的不一样,请参考 NULL。
假如文本文件中的字段比 Impala 表中的字段少,当 Impala 查询读取文件中的数据时,全部对应(缺乏)的列被设置为 NULL。
假如文本文件中的字段比 Impala 表中的字段多,当 Impala 查询读取文件中的数据时,多余的字段会被忽略。
你一样可使用手工 HDFS 操做如 hdfs dfs -put 或 hdfs dfs -cp 把数据文件放入 Impala 表数据目录。当你复制或移动新的数据文件到 Impala 表数据目录时,在执行对应这个表的查询以前,请先在 impala-shell 中执行 REFRESH table_name 语句,以便 Impala 识别到新增长的文件。
Cloudera Impala 支持采用 LZO 压缩的文本数据文件。当可行时,Cloudera 推荐压缩文本文件。 Impala 查询一般是 I/O密集的(I/O-bound);减小从硬盘上读取数据的数量一般会提升查询的速度,尽管在内存中解压数据时须要额外的 CPU 工做。
Impala 能够处理 LZO压缩文本文件,不支持 GZip 压缩文本文件。LZO 压缩文件是 "可分割的(splittable)",意味着文件的不一样部分能够在不一样的节点上独立的解压缩和处理。GZip 压缩文件是不可分割的,标志着它不适合 Impala 类型的分布式查询。
由于目前 Impala 能够读取 LZO 压缩数据文件而不能写入,你应当使用 Hive 进行初始化 CREATE TABLE 和加载数据,而后切换回 Impala 执行查询。关于为 Hive CREATE TABLE 和 INSERT 语句设置 LZO 压缩,参见 the LZO page on the Hive wiki。当你建立了 LZO 文本文件表以后,你也能够手工添加由 lzop 命令或相似方法产生的 LZO 压缩文本文件。
在 Impala 中使用 LZO压缩表以前,为集群中的每一台机器执行下面的一次性操做。使用 Cloudera 公共库、你创建的私有库、或者使用包文件,来安装所需的包。不管你是否使用 Cloudera Manager 产品来管理你的集群,你都须要手工执行这些步骤。
在使用 Cloudera Manager 管理的系统中,使用 parcels方式:
参考 Cloudera Manager 文档中的 setup instructions for the LZO parcel。
在使用 Cloudera Manager 管理的系统中,或非 Cloudera Manager 管理的系统中,使用包方式:
在你全部但愿使用 LZO 的 Impala 机器上,下载并安装对应的文件。这些文件都下载自 Cloudera GPL extras 下载站点。安装如下文件:
使用如下各组命令之一来刷新你的包管理系统库信息,为 Hadoop 安装基础的 LZO 支持,并为 Impala 安装 LZO 支持。
RHEL/CentOS:
$ sudo yum update $ sudo yum install hadoop-lzo-cdh4 # For clusters running CDH 4. $ sudo yum install hadoop-lzo # For clusters running CDH 5 or higher. $ sudo yum install impala-lzo
SUSE:
$ sudo apt-get update $ sudo zypper install hadoop-lzo-cdh4 # For clusters running CDH 4. $ sudo zypper install hadoop-lzo # For clusters running CDH 5 or higher. $ sudo zypper install impala-lzo
Debian/Ubuntu:
$ sudo zypper update $ sudo apt-get install hadoop-lzo-cdh4 # For clusters running CDH 4. $ sudo apt-get install hadoop-lzo # For clusters running CDH 5 or higher. $ sudo apt-get install impala-lzo
impala-lzo-cdh4 包的版本与你所使用的 Impala 版本紧密相关。当你更新了 Impala 以后,请在每一台应用机器上从新执行 impala-lzo 的安装命令,以确保你使用这个包的对应的版本。
<property> <name>io.compression.codecs</name> <value>org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.DeflateCodec, org.apache.hadoop.io.compress.SnappyCodec,com.hadoop.compression.lzo.LzopCodec</value> </property>
假如这是你第一次修改 Hadoop core-site.xml 文件,注意 /etc/hadoop/conf 目录一般是一个软连接,所以 core-site.xml 可能驻留在不一样的目录:
$ ls -l /etc/hadoop total 8 lrwxrwxrwx. 1 root root 29 Feb 26 2013 conf -> /etc/alternatives/hadoop-conf lrwxrwxrwx. 1 root root 10 Feb 26 2013 conf.dist -> conf.empty drwxr-xr-x. 2 root root 4096 Feb 26 2013 conf.empty drwxr-xr-x. 2 root root 4096 Oct 28 15:46 conf.pseudo
假如 core-site.xml 文件中缺乏 io.compression.codecs 属性,则只添加 com.hadoop.compression.lzo.LzopCodec 属性值,而不是像前面例子那样加上全部的编解码器。
包含 LZO压缩文本文件的表必须在 Hive 中使用一下存储子句建立:
STORED AS INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
此外,为了更好的效果,一些 Hive 设置是必需的。例如:
hive> SET mapreduce.output.fileoutputformat.compress=true; hive> SET hive.exec.compress.output=true; hive> SET mapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzopCodec; hive> CREATE TABLE lzo_t (s string) STORED AS > INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat' > OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'; hive> INSERT INTO TABLE lzo_t SELECT col1, col2 FROM uncompressed_text_table;
一当你建立了 LZO 压缩文本文件表以后,你能够经过在 Hive 中使用 INSERT ... SELECT 语句转换存储在其余表里(不管文件是何格式)的数据。
LZO压缩表的数据文件必须使用 .lzo 扩展名。当在 Hive 中执行 INSERT 以后,检查 HDFS 数据目录下的文件,确保这些文件具备正确的扩展名。 假如没有正确设置,带着正常的为压缩的文件结束,由于数据文件包含错误的格式(未压缩),Impala 将没法正确访问这个表(If the required settings are not in place, you end up with regular uncompressed files, and Impala cannot access the table because it finds data files with the wrong (uncompressed) format)。
当向 LZO 压缩文本文件表加载数据以后,请索引这些文件以便他们可分割(index the files so that they can be split)。经过运行 Java 类 com.hadoop.compression.lzo.DistributedLzoIndexer 来索引这些文件,须要在 Linux 命令行中执行。这一 Java 类包含在 hadoop-lzo 包里。
使用相似下面的命令运行索引器:
$ hadoop jar /usr/lib/hadoop/lib/hadoop-lzo-cdh4-0.4.15-gplextras.jar com.hadoop.compression.lzo.DistributedLzoIndexer /hdfs_location_of_table/
索引文件具备与他们所索引的文件相同的名称,后跟 .index 扩展名。加入数据文件没有被索引, Impala 查询将依然工做,可是查询将读取远端数据节点的数据,这将很是低效(Indexed files have the same name as the file they index, with the .index extension. If the data files are not indexed, Impala queries still work, but the queries read the data from remote DataNodes, which is very inefficient)。
当 LZO 压缩表建立,而且数据被加载和索引,你能够经过 Impala 查询它们。与往常同样,当在 Hive 中建立表以后,第一次启动 impala-shell 时,请先执行 INVALIDATE METADATA 语句以便 Impala 识别出新建立的表(在 Impala 1.2 及以上版本,你只须要在一个节点上运行 INVALIDATE METADATA ,而不是在全部的 Impala 节点上运行)。