Impala原理及其調優


Impala介紹

Impala支持的文件格式

Impala可以對Hadoop中大多數格式的文件進行查詢。它能通過create table和insert的方式將一部分格式的數據加載到table中,但值得注意的是,有一些格式的數據它是無法寫入的(write to)。對於Impala無法寫入的數據格式,我們只能通過Hive建表,通過Hive進行數據的寫入,然后使用Impala來對這些保存好的數據執行查詢操作。

文件類型

文件格式

壓縮編碼

能否CREATE ?

能否INSERT ?

Parquet

結構化

Snappy

GZIP

Text

非結構化

LZO

能。

如果建表時沒有指定存儲類型,默認采用未壓縮的text,字段由ASCII編碼的0x01字符串分割。

能。

如果使用了LZO壓縮,則只能通過Hive建表和插入數據。

Avro

結構化

Snappy

GZIP

Deflate

BZIP2

在Impala 1.4.0 或者更高的版本上支持,之前的版本只能通過Hive來建表。

不能。

只能通過LOAD DATA的方式將已經轉換好格式的數據加載進去,或者使用Hive來插入數據。

RCFile

結構化

Snappy

GZIP

Deflate

BZIP2

不能。

只能通過LOAD DATA的方式將已經轉換好格式的數據加載進去,或者使用Hive來插入數據。

SequenceFile

結構化

Snappy

GZIP

deflate

BZIP2

不能。

只能通過LOAD DATA的方式將已經轉換好格式的數據加載進去,或者使用Hive來插入數據。

 

Impala支持以下壓縮編碼:

  • Snappy – 推薦的編碼,因為它在壓縮率和解壓速度之間有很好的平衡性,Snappy壓縮速度很快,但是不如GZIP那樣能節約更多的存儲空間。Impala不支持Snappy壓縮的text file。
  • GZIP – 壓縮比很高能節約很多存儲空間,Impala不支持GZIP壓縮的text file。
  • Deflate – Impala不支持GZIP壓縮的text file。
  • BZIP2 - Impala不支持BZIP2壓縮的text file。
  • LZO – 只用於text file,Impala可以查詢LZO壓縮的text格式數據表,但是不支持insert數據,只能通過Hive來完成數據的insert。

Impapla如何執行查詢

下面這個圖表示了Impala在Hadoop集群中所處的位置:

Impala由以下的組件組成:

  • Clients – Hue、ODBC clients、JDBC clients、和Impala Shell都可以與Impala進行交互,這些接口都可以用在Impala的數據查詢以及對Impala的管理。
  • Hive Metastore – 存儲Impala可訪問數據的元數據。例如,這些元數據可以讓Impala知道哪些數據庫以及數據庫的結構是可以訪問的,當你創建、刪除、修改數據庫對象或者加載數據到數據表里面,相關的元數據變化會自動通過廣播的形式通知所有的Impala節點,這個通知過程由catalog service完成。
  • Cloudera Impala – Impala的進程運行在各個數據節點(Datanode)上面。每一個Impala的實例都可以從Impala client端接收查詢,進而產生執行計划、協調執行任務。數據查詢分布在各個Impala節點上,這些節點作為worker,並行執行查詢。
  • HBase和HDFS – 存儲用於查詢的數據。

Impala執行的查詢有以下幾個步驟:

  1. 客戶端通過ODBC、JDBC、或者Impala shell向Impala集群中的任意節點發送SQL語句,這個節點的impalad實例作為這個查詢的協調器(coordinator)。
  2. Impala解析和分析這個查詢語句來決定集群中的哪個impalad實例來執行某個任務。
  3. HDFS和HBase給本地的impalad實例提供數據訪問。
  4. 各個impalad向協調器impalad返回數據,然后由協調器impalad向client發送結果集。

Impala為什么比Hive速度快

Impala自稱數據查詢效率比Hive快幾倍甚至數十倍,它之所以這么快的原因大致有以下幾點:

  • 真正的MPP查詢引擎。
  • 使用C++開發而不是Java,降低運行負荷。
  • 運行時代碼生成(LLVM IR),提高效率。

  • 全新的執行引擎(不是Mapreduce)。
  • 在執行SQL語句的時候,Impala不會把中間數據寫入到磁盤,而是在內存中完成了所有的處理。
  • 使用Impala的時候,查詢任務會馬上執行而不是生產Mapreduce任務,這會節約大量的初始化時間。
  • Impala查詢計划解析器使用更智能的算法在多節點上分布式執行各個查詢步驟,同時避免了sorting和shuffle這兩個非常耗時的階段,這兩個階段往往是不需要的。
  • Impala擁有HDFS上面各個data block的信息,當它處理查詢的時候能夠在各個datanode上面更均衡的分發查詢。
  • 另外一個關鍵原因是,Impala為每個查詢產生匯編級的代碼,當Impala在本地內存中運行的時候,這些匯編代碼執行效率比其它任何代碼框架都更快,因為代碼框架會增加額外的延遲。

Impala核心組件

Impala Daemon

Impala的核心組件是運行在各個節點上面的impalad這個守護進程(Impala daemon),它負責讀寫數據文件,接收從impala-shell、Hue、JDBC、ODBC等接口發送的查詢語句,並行化查詢語句和分發工作任務到Impala集群的各個節點上,同時負責將本地計算好的查詢結果發送給協調器節點(coordinator node)。

你可以向運行在任意節點的Impala daemon提交查詢,這個節點將會作為這個查詢的協調器(coordinator node),其他節點將會傳輸部分結果集給這個協調器節點。由這個協調器節點構建最終的結果集。在做實驗或者測試的時候為了方便,我們往往連接到同一個Impala daemon來執行查詢,但是在生產環境運行產品級的應用時,我們應該循環(按順序)的在不同節點上面提交查詢,這樣才能使得集群的負載達到均衡。

Impala daemon不間斷的跟statestore進行通信交流,從而確認哪個節點是健康的能接收新的工作任務。它同時接收catalogd daemon(從Impala 1.2之后支持)傳來的廣播消息來更新元數據信息,當集群中的任意節點create、alter、drop任意對象、或者執行INSERT、LOAD DATA的時候觸發廣播消息。

Impala Statestore

Impala Statestore檢查集群各個節點上Impala daemon的健康狀態,同時不間斷地將結果反饋給各個Impala daemon。這個服務的物理進程名稱是statestored,在整個集群中我們僅需要一個這樣的進程即可。如果某個Impala節點由於硬件錯誤、軟件錯誤或者其他原因導致離線,statestore就會通知其他的節點,避免其他節點再向這個離線的節點發送請求。

由於statestore是當集群節點有問題的時候起通知作用,所以它對Impala集群並不是有關鍵影響的。如果statestore沒有運行或者運行失敗,其他節點和分布式任務會照常運行,只是說當節點掉線的時候集群會變得沒那么健壯。當statestore恢復正常運行時,它就又開始與其他節點通信並進行監控。

Impala Catalog

Imppalla catalog服務將SQL語句做出的元數據變化通知給集群的各個節點,catalog服務的物理進程名稱是catalogd,在整個集群中僅需要一個這樣的進程。由於它的請求會跟statestore daemon交互,所以最好讓statestored和catalogd這兩個進程在同一節點上。

Impala 1.2中加入的catalog服務減少了REFRESH和INVALIDATE METADATA語句的使用。在之前的版本中,當在某個節點上執行了CREATE DATABASE、DROP DATABASE、CREATE TABLE、ALTER TABLE、或者DROP TABLE語句之后,需要在其它的各個節點上執行命令INVALIDATE METADATA來確保元數據信息的更新。同樣的,當你在某個節點上執行了INSERT語句,在其它節點上執行查詢時就得先執行REFRESH table_name這個操作,這樣才能識別到新增的數據文件。需要注意的是,通過Impala執行的操作帶來的元數據變化,有了catalog就不需要再執行REFRESH和INVALIDATE METADATA,但如果是通過Hive進行的建表、加載數據,則仍然需要執行REFRESH和INVALIDATE METADATA來通知Impala更新元數據信息。

Impala與同類工具的性能對比

以下測試環境以及測試數據來自Impala官方博客。

環境配置

集群環境

所有的測試都在同一個集群上面運行,保證硬件環境的一致性。集群有21個節點,每個節點的配置都一樣:

  • 2個處理器、12核心、Intel Xeon CPU E5-2630L 0 2.00GHz
  • 12塊磁盤932GB(一個磁盤用於操作系統,其余的用於HDFS)
  • 384GB內存

對比環境

  • Impala 1.3.0
  • Hive-on-Tez: The final phase of the 18-month Stinger initiative (aka Hive 0.13)
  • Shark 0.9.2: A port of Hive from UC Berkeley AMPLab that is architecturally similar to Hive-on-Tez, but based on Spark instead of Tez. Shark testing was done on a native in-memory dataset (RDD) as well as HDFS.
  • Presto 0.60: Facebook’s query engine project

查詢環境

  • 為了確保Hadoop每個節點具有代表性的真實負載,所有的查詢在20個節點上的15TB數據集上進行。
  • 我們針對不同的處理工具統一采用Snappy壓縮,不同的工具選用其性能最佳的數據文件格式,Impala用Apache Parquet、Hive-on-Tez用ORC、Presto用RCFile、Shark用ORC。
  • 不同的處理工具都使用標准的測試技巧(多重運行、調優,等等)。

測試結果

單用戶場景

Impala on Parquet運行效率最高,比其后的Shark 0.9.2平均快了5倍。

多用戶場景

我們同時測試了單用戶和10個用戶做對比,測試中Impala更好的體現了其性能優勢,比其后的工具快了9.5倍。

吞吐量和硬件使用率

下面的CPU效率解釋了為什么Impala能夠做到低延遲和高吞吐量,絕大多數的性能和並發性都在於查詢引擎自身的CPU利用效率。

Impala調優

表和字段的統計分析

當數據表的統計信息可用的時候,Impala能夠更好的對查詢進行優化,通過統計信息它能更清楚的知道數據的分布情況,並有效地並行處理和分發工作任務。

在之前,Impala依賴於Hive的機制產生mapreduce任務來收集統計信息。為了更好的用戶體驗和可靠性,Impala在1.2.2及其之后的版本中實現了自己的COMPUTE STATS語法來進行信息統計,結合使用SHOW TABLE STATS和SHOW COLUMN STATS這兩種語法。

用Impala統計表和字段信息的例子如下:

[localhost:21000] > show table stats store;
+-------+--------+--------+--------+
| #Rows | #Files | Size   | Format |
+-------+--------+--------+--------+
| -1    | 1      | 3.08KB | TEXT   |
+-------+--------+--------+--------+
Returned 1 row(s) in 0.03s
[localhost:21000] > show column stats store;
+--------------------+-----------+------------------+--------+----------+----------+
| Column             | Type      | #Distinct Values | #Nulls | Max Size | Avg Size |
+--------------------+-----------+------------------+--------+----------+----------+
| s_store_sk         | INT       | -1               | -1     | 4        | 4        |
| s_store_id         | STRING    | -1               | -1     | -1       | -1       |
| s_rec_start_date   | TIMESTAMP | -1               | -1     | 16       | 16       |
| s_rec_end_date     | TIMESTAMP | -1               | -1     | 16       | 16       |
| s_closed_date_sk   | INT       | -1               | -1     | 4        | 4        |
| s_store_name       | STRING    | -1               | -1     | -1       | -1       |
| s_number_employees | INT       | -1               | -1     | 4        | 4        |
| s_floor_space      | INT       | -1               | -1     | 4        | 4        |
| s_hours            | STRING    | -1               | -1     | -1       | -1       |
| s_manager          | STRING    | -1               | -1     | -1       | -1       |
| s_market_id        | INT       | -1               | -1     | 4        | 4        |
| s_geography_class  | STRING    | -1               | -1     | -1       | -1       |
| s_market_desc      | STRING    | -1               | -1     | -1       | -1       |
| s_market_manager   | STRING    | -1               | -1     | -1       | -1       |
| s_division_id      | INT       | -1               | -1     | 4        | 4        |
| s_division_name    | STRING    | -1               | -1     | -1       | -1       |
| s_company_id       | INT       | -1               | -1     | 4        | 4        |
| s_company_name     | STRING    | -1               | -1     | -1       | -1       |
| s_street_number    | STRING    | -1               | -1     | -1       | -1       |
| s_street_name      | STRING    | -1               | -1     | -1       | -1       |
| s_street_type      | STRING    | -1               | -1     | -1       | -1       |
| s_suite_number     | STRING    | -1               | -1     | -1       | -1       |
| s_city             | STRING    | -1               | -1     | -1       | -1       |
| s_county           | STRING    | -1               | -1     | -1       | -1       |
| s_state            | STRING    | -1               | -1     | -1       | -1       |
| s_zip              | STRING    | -1               | -1     | -1       | -1       |
| s_country          | STRING    | -1               | -1     | -1       | -1       |
| s_gmt_offset       | FLOAT     | -1               | -1     | 4        | 4        |
| s_tax_precentage   | FLOAT     | -1               | -1     | 4        | 4        |
+--------------------+-----------+------------------+--------+----------+----------+
Returned 29 row(s) in 0.04s

[localhost:21000] > compute stats store;

+------------------------------------------+

| summary                                  |

+------------------------------------------+

| Updated 1 partition(s) and 29 column(s). |

+------------------------------------------+

Returned 1 row(s) in 1.88s

[localhost:21000] > show table stats store;

+-------+--------+--------+--------+

| #Rows | #Files | Size   | Format |

+-------+--------+--------+--------+

| 12    | 1      | 3.08KB | TEXT   |

+-------+--------+--------+--------+

Returned 1 row(s) in 0.02s

[localhost:21000] > show column stats store;

+--------------------+-----------+------------------+--------+----------+----------------+

| Column             | Type      | #Distinct Values | #Nulls | Max Size | Avg Size          |

+--------------------+-----------+------------------+--------+----------+----------------+

| s_store_sk         | INT       | 12               | -1     | 4        | 4                 |

| s_store_id         | STRING    | 6                | -1     | 16       | 16                |

| s_rec_start_date   | TIMESTAMP | 4                | -1     | 16       | 16                |

| s_rec_end_date     | TIMESTAMP | 3                | -1     | 16       | 16                |

| s_closed_date_sk   | INT       | 3                | -1     | 4        | 4                 |

| s_store_name       | STRING    | 8                | -1     | 5        | 4.25              |

| s_number_employees | INT       | 9                | -1     | 4        | 4                 |

| s_floor_space      | INT       | 10               | -1     | 4        | 4                 |

| s_hours            | STRING    | 2                | -1     | 8        | 7.08330011367797 |

| s_manager          | STRING    | 7                | -1     | 15       | 12                |

| s_market_id        | INT       | 7                | -1     | 4        | 4                 |

| s_geography_class  | STRING    | 1                | -1     | 7        | 7                 |

| s_market_desc      | STRING    | 10               | -1     | 94       | 55.5              |

| s_market_manager   | STRING    | 7                | -1     | 16       | 14                |

| s_division_id      | INT       | 1                | -1     | 4        | 4                 |

| s_division_name    | STRING    | 1                | -1     | 7        | 7                 |

| s_company_id       | INT       | 1                | -1     | 4        | 4                 |

| s_company_name     | STRING    | 1                | -1     | 7        | 7                 |

| s_street_number    | STRING    | 9                | -1     | 3        | 2.83330011367797 |

| s_street_name      | STRING    | 12               | -1     | 11       | 6.58330011367797 |

| s_street_type      | STRING    | 8                | -1     | 9        | 4.83330011367797 |

| s_suite_number     | STRING    | 11               | -1     | 9        | 8.25              |

| s_city             | STRING    | 2                | -1     | 8        | 6.5               |

| s_county           | STRING    | 1                | -1     | 17       | 17                |

| s_state            | STRING    | 1                | -1     | 2        | 2                 |

| s_zip              | STRING    | 2                | -1     | 5        | 5                 |

| s_country          | STRING    | 1                | -1     | 13       | 13                |

| s_gmt_offset       | FLOAT     | 1                | -1     | 4        | 4                 |

| s_tax_precentage   | FLOAT     | 5                | -1     | 4        | 4                 |

+--------------------+-----------+------------------+--------+----------+----------------

Returned 29 row(s) in 0.04s 

啟用block location跟蹤

當在Impala上執行查詢的時候,會多個datanode上分布式地讀取block數據,如果Impala擁有更多的block信息,將會更高效的獲取數據並處理。可以通過以下步驟來啟用block location跟蹤:

  1. 修改hdfs-site.xml文件添加以下內容:
    <property>
        <name>dfs.datanode.hdfs-blocks-metadata.enabled</name>
        <value>true</value>
    </property>
  2. 拷貝Hadoop集群的hdfs-site.xml和core-site.xml文件到各個Impala節點的配置目錄/etc/impala/conf中。
  3. 重啟Hadoop集群中的所有datanode。

啟用native checksumming

對大量數據計算校驗和(checksum)會帶來巨大的時間損耗,因此用本地庫(native library)來執行校驗和會帶來性能上的提升。在Impala中可以采用以下方式來啟用本地校驗:

  • 如果Impala是用Cloudera Manager部署的,默認已經開啟了本地校驗。
  • 如果是手動安裝的Impala,你必須手動安裝Hadoop本地庫libhadoop.so,如果這個本地庫找不到,你會在Impala日志中看到這樣的信息:"Unable to load native-hadoop library for your platform... using built-in-java classes where applicable"。

允許Impala執行short-circuit read

Short-circuit read意味着會從datanode的本地文件系統直接讀取數據,而不用首先與datanode進行通信,這肯定會提高性能。你必須使用Cloudera CDH 4.2或更高的版本來達到快速的short-circuit讀取數據。可以通過以下步驟來進行設置:

  1. 修改各個Impala節點上的hdfs-site.xml文件:
    <property>
        <name>dfs.client.read.shortcircuit</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.domain.socket.path</name>
        <value>/var/run/hadoop-hdfs/dn._PORT</value>
    </property>
    <property>
        <name>dfs.client.file-block-storage-locations.timeout</name>
        <value>3000</value>
    </property>
  2. 確保/var/run/hadoop-hdfs/目錄對用戶是可寫入的。
  3. 拷貝Hadoop集群的hdfs-site.xml和core-site.xml文件到各個Impala節點的配置目錄/etc/impala/conf中。
  4. 重啟Hadoop集群中的所有datanode。

增加更多的Impala節點

事實證明更多的Impala節點會顯著地提高性能,這跟Hadoop使用更多的datanode提高性能是一樣的。擁有更多的節點會讓數據分散到更多的節點上,在執行查詢的時候能夠分發更多的任務並行執行,從而提高整體執行性能。

執行查詢時優化內存的使用

在啟動Impala守護進程的時候可以使用-mem_limits參數來限制內存消耗,這個參數只對查詢(query)進行內存限制。

查詢的執行依賴於內存

如果數據集太大以至於超出了機器的可用內存,這個查詢將會失敗。Impala對內存的使用並不直接根據數據集的大小決定,它是根據查詢的類型而變化的。聚合查詢需要的內存跟group之后的數據量一樣,連接查詢(join)需要的內存量等價於除開最大表之外的所有表的總大小。

采用資源隔離

如果你使用的是Cloudera Manager,可以使用Cloudera Manager的設備控制器(cgroups)機制來實現資源隔離(resource isolation)。更多信息請閱讀Cloudera Manager文檔中對resource isolation的描述。

 

----end

本文連接:http://www.cnblogs.com/chenz/articles/3947147.html

作者:chenzheng

聯系:vinkeychen@gmail.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM