Impala 表使用文本數據文件

Impala 表使用文本數據文件

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

Impala 文本文件表的查詢性能


數據存放成文本文件是至關笨重的,而且不如二進制格式如 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 表裏,而後導出這些表數據目錄下的數據文件。

  Note:

不要在你構建的文本數據文件中的值上包以引號。假如你須要在字段值裏包含分隔符,例如把一個包含逗號的字符串值放入 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 文本文件表

加載已有的文本文件到 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'));
  Note: 由於 Impala 和 HDFS 基礎架構是專門針對大文件( multi-megabyte files)優化的,當插入多行數據時避免使用 INSERT ... VALUES 語句。每個 INSERT ... VALUES 語句生成一個新的小文件,會致使文件碎片和下降性能。當建立任意大量數據時,使用批量佳志技術,如 LOAD DATA 或 INSERT ... SELECT。或者爲單行插入操做 使用 HBase 表, 由於做爲存儲在 HDFS中的表,HBase 表不會受到碎片化的影響(because HBase tables are not subject to the same fragmentation issues as tables stored on HDFS)。

當爲 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 識別到新增長的文件。

使用 LZO 壓縮文本文件

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 壓縮文本文件。

使用 LZO壓縮文本文件前的準備

在 Impala 中使用 LZO壓縮表以前,爲集羣中的每一臺機器執行下面的一次性操做。使用 Cloudera 公共庫、你創建的私有庫、或者使用包文件,來安裝所需的包。不管你是否使用 Cloudera Manager 產品來管理你的集羣,你都須要手工執行這些步驟。

  1. 使用 Cloudera 庫,設置你的系統支持 LZO:

    在使用 Cloudera Manager 管理的系統中,使用 parcels方式:

    參考 Cloudera Manager 文檔中的 setup instructions for the LZO parcel

    在使用 Cloudera Manager 管理的系統中,或非 Cloudera Manager 管理的系統中,使用包方式:

    在你全部但願使用 LZO 的 Impala 機器上,下載並安裝對應的文件。這些文件都下載自 Cloudera GPL extras 下載站點。安裝如下文件:

  2. 配置 Impala 使用 LZO:

    使用如下各組命令之一來刷新你的包管理系統庫信息,爲 Hadoop 安裝基礎的 LZO 支持,併爲 Impala 安裝 LZO 支持。

      Note: CDH 4 和 CDH 5 中的 Hadoop LZO 包名發生了變化。在 CDH 4 中,包名是 hadoop-lzo-cdh4。在 CDH 5 中,包名是 hadoop-lzo。根據你集羣中 CDH 版本的不一樣使用不一樣的包名。

    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
      Note:

    impala-lzo-cdh4 包的版本與你所使用的 Impala 版本緊密相關。當你更新了 Impala 以後,請在每一臺應用機器上從新執行 impala-lzo 的安裝命令,以確保你使用這個包的對應的版本。

  3. 修改客戶端服務端的 core-site.xml 文件(也就是說,同時在 Impala 和 Hadoop 的配置目錄中),在使用逗號分隔的編解碼器列表裏追加 com.hadoop.compression.lzo.LzopCodec 。例如:
    <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>
      Note:

    假如這是你第一次修改 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 屬性值,而不是像前面例子那樣加上全部的編解碼器。

  4. 重啓 MapReduce 和 Impala 服務

建立 LZO 壓縮文本文件表

包含 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/
  Note: 假如上面的例子裏的 JAR 文件路徑不正確,執行  find 命令來定位  hadoop-lzo-*-gplextras.jar 的位置,而後使用正確的路徑。

索引文件具備與他們所索引的文件相同的名稱,後跟 .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 節點上運行)。

相關文章
相關標籤/搜索