1. 程式人生 > >Cloudera Impala 常見問題(翻譯)

Cloudera Impala 常見問題(翻譯)

Cloudera Impala 常見問題

下面是 Clouder Impala 產品常見問題的目錄。

繼續閱讀:

Trying Impala

如何實驗 Cloudera Impala?

想要試試 Impala 的核心特性和功能,最簡便的實驗 Impala 的方法就是下載 Cloudera QuickStart VM 並通過 Cloudera Manager 啟動 Impala 服務,然後在終端視窗使用 impala-shell,或者在Hue web 介面中使用  Impala Query UI。

想要在叢集中測試 Impala 的效能並實驗管理特性,你需要超越 QuickStart VM 和它的虛擬化的單節點環境。理想情況下,下載 Cloudera Manager 軟體來設定叢集,然後通過 Cloudera Manager 安裝 Impala。

Cloudera 是否提供演示 Impala 的 VM 環境?

Cloudera 提供演示 VM 環境 QuickStart VM,包含 VMWare, VirtualBox, KVM 三種格式。更多資訊,參見 the Cloudera QuickStart VM。啟動 QuickStart VM 後,其中許多服務預設是關閉的;在自動出現的 Cloudera Manager UI 中,啟用 Impala 和其他你想要實驗的元件

在哪裡可以找到 Impala 文件

參見 Impala Documentation 瞭解 Impala 

版本說明、關於 Impala 安裝更新配置、以及 Impala 查詢語言的資訊。

在哪裡可以瞭解到更多的 Impala 的資訊?

這裡有更多 Impala 產品的資訊:

在 Cloudera Announcements 論壇檢視最新的 Impala 公告。

在哪裡提問和提交 Impala 的反饋?

在哪裡可以下載樣例資料進行測試?

你可以在 this Github repository 獲得生成資料檔案並設定 TPC-DS 型別基準測試環境的指令碼。除了可以用於效能試驗外,這些表也適用於測試 Impala SQL 的許多方面:他們包含了各種資料型別、資料分佈、分割槽、以及適合連線查詢的關係資料。

Impala System Requirements

執行 Impala 有什麼軟硬體方面的需求?

關於 Impala 的需求,參見 Cloudera Impala Requirements。需要注意的是,對於給定版本的 Impala,通常有一個最小支援的 Clouder Manager 版本。

需要多少記憶體?

儘管 Impala 不是記憶體資料庫,當處理大的表和大的結果集時,你應當期待為 impalad 守護程序分配大量的實體記憶體(you should expect to dedicate a substantial portion of physical memory for the impalad daemon)。推薦 Impala 節點具有至少 128 GB 記憶體。Impala 操作所需的記憶體依賴於幾個因素:

  • 表的檔案格式。相同的資料,採用不同的檔案格式,資料檔案個數也不同。為了分析資料,根據每個檔案所採用的壓縮和編碼格式的不同,可能需要不同資料量的臨時記憶體來進行解壓(The compression and encoding for each file format might require a different amount of temporary memory to decompress the data for analysis)
  • 是否為 SELECT 或 INSERT 操作。例如,查詢 Parquet 表時需要相對較少的記憶體,因為 Impala 以 8MB /塊來進行讀取和解壓縮資料。而向 Parquet 表插入資料則是記憶體密集型操作,因為每一個數據檔案(最大大小為 1GB)的資料被放在記憶體中,直到編碼、壓縮並寫入硬碟
  • 表是否為分割槽表,並且針對分割槽表的查詢是否可以從分割槽修剪(partition pruning)中受益
  • 最終的結果集是否使用 ORDER BY 子句來排序。請記住,Impala 要求所有包含的 ORDER BY 子句的查詢同時包含 LIMIT 子句,或者在語句中直接包含,或者隱式的通過 DEFAULT_ORDER_BY_LIMIT 查詢選項設定來實現。每一個 Impala 節點掃描並過濾總資料的一部分,並且對他們自己那部分資料應用 LIMIT。中間結果集 (包含最大 LIMIT 行記錄)都發送回協調節點,在上面執行最終的排序並對最終結果集應用 LIMIT 子句。例如,假如你執行查詢:
    select * from giant_table order by some_column limit 1000;
    並且你的叢集有 50 個節點,然後這 50 個節點每個節點將傳遞最多 1000 行記錄給協調節點。協調節點需要足夠的記憶體進行排序(LIMIT *叢集節點數) ,儘管這時最終的結果集最多返回 1000 行。
  • 結果集的大小。當中間結果集在節點之間傳輸時,傳輸資料的數量依賴於查詢返回列的數量。例如,在結果集中只返回實際所需列的查詢比總是使用 SELECT * 的查詢消耗更少的記憶體
  • 連線查詢工作如何拆分的機制

如何 Impala 節點在處理中間結果集時超出了預留給 Impala 記憶體的限制,目前 Impala 不支援"溢位的硬碟(spill to disk)"。假如這對你的情況來說是個問題(例如連線兩個非常大的表時),更多記憶體是有益的。

參見 Hardware Requirements 瞭解更詳細的資訊以及 Impala 硬體方面的先決條件。

Cloudera 推薦哪種處理器?

Impala 使用 SSE4.2 指令。對應 Intel 的 Nehalem+ 晶片和 AMD 的 Bulldozer+ 晶片。Impala 可以在較老的機器上正常執行,但無法達到最佳效能。

Supported and Unsupported Functionality In Impala

Impala 支援下列功能:

  • SQL 和 HiveQL 命令的一個大的子集,包括 SELECT 、 INSERT 、joins。更多資訊,參見 Impala SQL Language Reference.
  • 使用 Cloudera Manager 管理 Impala。請使用 Cloudera Manager 4.6 及以上版本,你可以部署和管理你的 Impala 服務。在叢集中使用 Impala ,使用 Cloudera Manager 是最佳入門方式。 更多資訊,參見 Cloudera Manager Installation Guide 中使用 Cloudera Manager 安裝 Impala 的主題
  • 使用 Hue 進行查詢
  • 通過 INSERT 語句向表中追加和插入資料。參見 How Impala Works with Hadoop File Formats 瞭解關於哪種檔案格式的哪些操作可以支援的詳細資訊
  • ODBC: Impala 是認證支援 MicroStrategy 和 Tableau的,但是有一些限制。更多資訊,參見 Configuring Impala to Work with ODBC.
  • 在單個查詢中同時查詢 HDFS 和 HBase 中的資料。參見 Using Impala to Query HBase Tables 瞭解詳細資訊
  • 併發客戶端請求。每一個 Impala 守護程序可以處理多併發客戶端請求。對效能的影響依賴於你特定的硬體和負載
  • Kerberos 認證。更多資訊參見 Impala Security.
  • 分割槽。在 Impala SQL 中,你可以使用 CREATE TABLE 語句建立分割槽表,使用 ALTER TABLE 語句新增、刪除分割槽。Impala 同樣會從之前 Hive 中的分割槽表。參見 Partitioning 瞭解詳細資訊

Impala 不支援下列功能:

  • 流資料查詢(Querying streaming data)
  • 刪除個別行。你可以通過覆蓋整個表或分割槽、或刪除表來批量刪除資料
  • 索引(暫不支援)。像在 Using LZO-Compressed Text Files 中描述的那樣,LZO 壓縮文字檔案可以在 Impala 之外進行索引
  • 文字欄位的全文檢索。這時候請使用 Cloudera Search 產品
  • 自定義 Hive 序列化/反序列化(Serializer/Deserializer) 類(SerDes)。Impala 支援一組通用的本地檔案格式,在 CDH 中有對應的內建的 SerDes。參見 How Impala Works with Hadoop File Formats 瞭解詳細資訊
  • 執行中查詢的故障轉移。假如執行查詢的任意主機失敗,目前來說 Impala 是取消所執行的查詢。當一個或多個主機下線,Impala 會重新路由之後的查詢並只使用可用的主機,當主機重新上線時 Impala 可以檢測到,並重新使用它們。因為查詢可以通過任意 Impala 節點提交,所以不會出現單點故障。將來我們會為 Impala 新增額外的工作分配功能,這樣即使出現主機失敗也會完成整個查詢
  • Impala 守護程序之間的加密資料傳輸
  • 視窗函式(Window functions)
  • Hive 索引
  • 非 Hadoop 資料來源,如關係資料庫

關於更詳細的不支援的 HiveQL 特性列表,參見 SQL Differences Between Impala and Hive

Impala 是否支援通用 JDBC?

Impala 支援 HiveServer2 JDBC 驅動。

是否支援 Avro?

是的,支援 Avro。Impala 可以查詢 Avro 表。但目前你必須在 Hive 中建立表並載入資料。參見 Using the Avro File Format with Impala Tables 瞭解詳細資訊。

What's next for Cloudera Impala?

請看我們的部落格: http://blog.cloudera.com/blog/2012/12/whats-next-for-cloudera-impala/

How do I?

如何避免使用者看到 SQL 查詢的內容?

關於如何設定 Impala 日誌對未授權的使用者不可讀的介紹,參見 Securing Impala Data and Log Files.

關於web 介面對 Impala 日誌檔案和其他內部伺服器資訊的密碼保護(For instructions on password-protecting the web interface to the Impala log files and other internal server information),參見 Securing the Impala Web User Interface

如何知道叢集中有多少 Impala 節點?

Impala statestore 會跟蹤當前有多少 impalad 節點可用。你可以通過 statestore 的 web 介面看到這些資訊。例如,在 http://statestore_host:25010/metrics 你可以看到類似下面的行:

statestore.live-backends:3
statestore.live-backends.list:[host1:22000,host1:26000,host2:22000]

其中 impalad 節點的個數是列出的物件中使用 22000 埠的物件的個數,這裡是 2 個(通常這個數值比 statestore.live-backends 報告的數值少一)。假如一個 impalad 不可用,經過停機後恢復正常,那本頁報告的資訊會對應的修改。

Impala Performance

查詢結果是一可用就返回還是等查詢完成後一次全部返回?

Impala 儘可能的一有結果就輸出來。特定的 SQL 操作(聚合函式或排序操作) 需要所有的結果都準備好才可以返回。

為什麼我的查詢執行緩慢?

一個查詢執行的慢可能有許多原因。使用下面的列表,診斷已有查詢效能問題,在寫新的查詢時避免出現這些問題,配置新的節點,建立新的表,或者載入資料。

  • 在查詢完成之後,在 impala-shell 中立即執行 PROFILE 命令。對於指定的節點,其中 BytesRead、BytesReadLocal、BytesReadShortCircuit 的值應當一致。例如:
    - BytesRead: 180.33 MB
    - BytesReadLocal: 180.33 MB
    - BytesReadShortCircuit: 180.33 MB
    假如 BytesReadLocal 低於 BytesRead,你叢集中的一些配置可能錯了, 例如 impalad 守護程序沒有在全部資料節點上都執行。假如 BytesReadShortCircuit 低於 BytesRead,這一節點上可能沒有啟用 short-circuit 讀;參見 Post-Installation Configuration for Impala 瞭解相關資訊
  • 假如表剛剛建立,或者是在 INVALIDATE METADATA 語句之後或者 impalad 守護程序剛剛重啟之後第一次訪問這個表,當表元資料被載入和快取時,可能有一些延遲。請檢查再次執行查詢時候放緩是否消失。在進行效能對比時,考慮先對每一個表執行一個 DESCRIBE table_name 語句,以確保所有的計時都只記錄了實際的查詢時間而不是包含載入表元資料的一次性等待
  • 表資料使用的是未壓縮的文字格式?請使用 DESCRIBE FORMATTED table_name 語句檢查。文字檔案表使用下面的語句標識:
    InputFormat: org.apache.hadoop.mapred.TextInputFormat
    儘管對於不包含 STORED AS 子句的 CREATE TABLE 語句,預設使用未壓縮的文字檔案格式,但它是佔用硬碟空間最大的格式,所以也是查詢最慢的格式。對於查詢效能很關鍵的資料,特別是頻繁查詢的表,請考慮開始或轉換成緊湊的二進位制檔案格式,如Parquet 、Avro、RCFile、SequenceFile。詳細資訊,參見 How Impala Works with Hadoop File Formats
  • 假如你的表有非常多的列,但是查詢僅涉及其中少量的列,請考慮使用 Parquet 檔案格式。它的資料檔案被組織成面向列(column-oriented)的佈局, 可以讓檢索、過濾和彙總特定列的值的 I/O 需求量最小化。參見 Using the Parquet File Format with Impala Tables 瞭解詳細資訊
  • 假如你的查詢涉及到很多連線,這些表是正確的順序嗎,以便返回最多行的表或子查詢放在最左側(If your query involves any joins, are the tables in the query ordered so that the tables or subqueries are ordered with the ones returning the largest number of rows on the left)? 這一順序允許 Impala 優化節點之間如何分佈工作,以及中間結果集如何從一個節點向另外一個節點路由。例如,其他部分都相同,下面連線順序的查詢是高效的查詢:
    select some_col from
        huge_table join big_table join medium_table join small_table
      where
        huge_table.id = big_table.id
        and big_table.id = medium_table.id
        and medium_table.id = small_table.id;
    參見 Performance Considerations for Join Queries 瞭解連線查詢的效能提示
  • 同樣對於連線查詢,在你的連線子句中使用的表、列是否都有統計資訊?列統計資訊讓 Impala 更好的選擇如何為連線查詢的各個部分分配工作。參見 How Impala Uses Statistics for Query Optimization 瞭解採集統計資訊的詳細資訊
  • 你的表是否由大量的小資料檔案組成?Impala 對大資料檔案更高效(Impala works most efficiently with data files in the multi-megabyte range);Parquet 是一種專為資料倉庫類的查詢優化的檔案格式,採用 1GB 的檔案和 1GB 塊大小。在 impala-shell 中使用 DESCRIBE FORMATTED table_name 語句來查看錶的資料位置,並使用 hadoop fs -ls 或 hdfs dfs -ls Unix 命令檢視檔案以及大小。假如你有成千上萬個小資料檔案,這就是你應當合併成更少的大資料檔案的訊號。使用 INSERT ... SELECT 語句複製資料到新表,這一過程包含重組到新資料檔案的部分。寧可構建大的資料檔案並通過 LOAD DATA 或 CREATE EXTERNAL TABLE 語句採用批量的方式匯入,也不用採用 INSERT ... VALUES 語句的方式;每一個 INSERT ... VALUES 語句建立一個單獨的極小的資料檔案。假如你在同一個目錄下有成千上萬的資料檔案,但每一個有幾兆大(but each one is megabytes in size,), 考慮使用分割槽表,以便每一個分割槽包含較少量的檔案。請參閱下面更多的分割槽說明
  • 假如你的資料易於根據時間或地理位置分組,那麼你根據對應的列如年、月、和/或日分割槽了嗎?基於特定列的分割槽表允許查詢查詢根據這些列過濾,避免讀取無關年份、無關郵編等等的資料(不要分割槽成太細的粒度;分割槽構建成每個分割槽下都有足夠的資料,以便從 multi-megabyte HDFS block size 中受益)。參見 Partitioning 瞭解詳細資訊

為什麼我的 SELECT 查詢會失敗?

當一個 SELECT 語句失敗了,原因通常是以下類別之一:

  • 因為效能、容量、或網路問題影響了特定的節點導致的超時
  • 連線查詢的過多記憶體數用,這一查詢的結果會自動取消
  • 處理查詢中特定的 WHERE 子句時,影響到每一節點上原生代碼如何生成的底層問題。例如,特定節點上可能會生成它的處理器不支援的機器指令。假如日誌中的錯誤資訊猜測是無效指令(illegal instruction),考慮臨時關閉生成原生代碼,並重試這個查詢
  • 異常的輸入資料,例如包含一個巨大的長行的文字資料檔案(a text data file with an enormously long line),或者使用了沒有在 CREATE TABLE 語句中 FIELDS TERMINATED BY 子句中設定的分隔符(or with a delimiter that does not match the character specified in the FIELDS TERMINATED BY clause of the CREATE TABLEstatement)

 

 

為什麼我的 INSERT 查詢會失敗?

當 INSERT 語句失敗時,通常是因為超出 Hadoop 元件的一些限制,特別是 HDFS。

  • 由於可能會在 HDFS 併發開啟許多檔案和關聯的程序,插入到分割槽表的操作是一個費力(strenuous)操作。Impala 1.1.1 包含了一些改進,以更有效的分發工作,這樣每個分割槽使用一個節點寫入值,而不是沒一個節點一個單獨的資料檔案
  • INSERT 語句中 SELECT 部分的特定表示式會產生複雜的執行計劃,並導致低效的 INSERT 操作。請儘量使源表和目標表中列的資料型別匹配,例如,如果必要,在源表上執行 ALTER TABLE ... REPLACE COLUMNS 語句。請儘量避免在 SELECT 位置使用 CASE 表示式,因為相比保持列不變或通過內建函式轉換列,CASE 會導致結果更難預測
  • 請做好準備提升你的 HDFS 配置設定中的一些限制,可以臨時的在 INSERT 執行時,如果你頻繁執行這些 INSERT 語句作為 ETL 管道的一部分,也可以永久修改
  • 依賴於目標表的檔案格式,INSERT 語句的資源使用可能會變化。插入到 Parquet 表是記憶體密集型操作,因為每一個分割槽的資料會快取到記憶體裡,直到它達到 1G,這時候資料檔案才寫入到硬碟。當執行 INSERT 語句時候,如果查詢中源表的統計資訊可用,Impala 可以更高效的分佈工作。參見 How Impala Uses Statistics for Query Optimization 瞭解如何採集統計資訊

當部署到叢集中更多主機上時, Impala 效能會提升嗎?就像 Hadoop 效能那樣?

是的。Impala 效能隨主機數而擴充套件(Impala scales with the number of hosts)。在叢集中所有資料節點上安裝 Impala 很重要,否則的話,一些節點必須進行遠端讀取以獲得本地讀取無法獲得的資料。對於 Impala 效能來說,資料本地化(Data locality) 是一個重要的架構方面(architectural aspect)。參見 this Impala performance blog post 瞭解背景資訊。請注意這些部落格使用 Impala 1.1.1 進行的基準測試;在 Impala 1.2.x 系列中,已經添加了更多效能特性。

減少 HDFS 塊大小會實現更快的查詢結果嗎?

不會。Impala 不會對 HDFS 或 HBase 資料集做任何修改。

預設的 Parquet 塊大小已經相當的大(1GB),並且在建立 Parquet 檔案時使用 PARQUET_FILE_SIZE 查詢選項可以控制塊大小。

Impala 使用快取嗎?

Impala 不會快取資料,但它快取一些表和檔案的元資料。儘管因為資料集被快取到 OS 的緩衝區中,接下來的重複查詢可能執行的更快,Impala 不會明確的控制這些。

Impala Use Cases

什麼情況下適合使用 Impala 而不適合 Hive 和 MapReduce?

Impala 非常適合在大的資料集上,為互動式探索分析執行 SQL。Hive 和 MapReduce 則適合長時間執行的、批處理的任務,例如 ETL。

Impala 是否需要 MapReduce ?如果 MapReduce 停了,Impala 是否能正常工作?

Impala 根本用不到 MapReduce。

Impala 是否可以用於複雜事件處理?

例如,在工業環境中,許多客戶端可能產生大量的資料。Impala 是否可用與分析這些資料,發現環境中顯著的變化?

複雜事件處理(Complex Event Processing,CEP) 通常使用專門的流處理系統處理。Impala 不是流處理系統,它其實更像關係資料庫。

Is Impala intended to handle real time queries in low-latency applications or is it for ad hoc queries for the purpose of data exploration?

即席查詢(Ad-hoc)是 Impala 的主要使用情況。我們估計它會在許多需要低延遲的環境中使用。Impala 是否適合某個特定的情況依賴於此時的負載、資料大小和查詢次數。參見 Impala Benefits 瞭解使用 Impala 可以獲得的主要益處。

Questions about Impala And Hive

Impala 與 Hive 和 Pig 有什麼異同?

Impala 與 Hive 和 Pig 不同,因為它使用自己的守護程序,跨叢集分散式進行查詢。因為 Impala 不依賴於 MapReduce,它避免了 MapReduce 作業的啟動開銷,讓 Impala 能實時返回結果。

我是否可以改變或新增新功能(functionality)?

Impala 1.2 開始支援 UDFs。你可以使用 C++ 寫你自己的函式,或者重用已有的基於 Java 的 Hive UDFs。支援的 UDF 包括標量函式和使用者定義聚合函式(UDAs)。目前不支援使用者定義表函式(UDTFs)。

Impala 目前不支援擴充套件序列號-反序列化(serialization-deserialization)框架(SerDes),因此為 Impala 新增擴充套件功能不像 Hive 或 Pig 那麼簡單。

Impala 中的所有查詢都可以在 Hive 中執行嗎?

是的。儘管在一些查詢如何處理方面有細微的差別,但是 Impala 查詢也可以在 Hive 中完成。Impala SQL 是 HiveQL 的子集,有一些功能限制如變換(transforms)。關於具體的 Impala SQL 方言,參見 SQL Statements。關於 Impala 內建函式,參見 Built-in Functions。關於不支援的 HiveQL 特性,參見 SQL Differences Between Impala and Hive

我可以用 Impala 查詢已經在 Hive 和 HBase 載入的資料嗎?

允許 Impala 查詢 Hive 管理的表,不管它是存放在 HDFS 還是 HBase中,都不需要額外的步驟。請確保已經正確的配置 Impala 訪問 Hive metastore,並且你準備好了。請記住,預設的 impalad 使用 impala 使用者執行,所以你可能需要調整一些檔案的許可權,這取決於你目前許可權多麼嚴格。

參見 Using Impala to Query HBase Tables 瞭解查詢 HBase 中資料的詳細資訊。

Impala 是否需要 Hive?

Hive metastore 服務是必需的。Impala 與 Hive 共享同一個 metastore 資料庫,透明的允許 Impala 和 Hive 訪問相同的表。

Hive 本身是可選的,並且不需要跟 Impala 安裝在同一個節點上。相比目前 Impala 支援的寫(插入)操作(的檔案格式),Impala 支援更多型別的讀取(查詢)操作;對於使用的特定的檔案格式,你應當使用 Hive 向表裡插入資料。參見 How Impala Works with Hadoop File Formats 瞭解詳細資訊。

Impala Availability

Impala 可以用於生產環境嗎?

Impala 已經完成了它的測試版本釋出週期,1.0 GA 版本已經為生產環境做好準備。而 1.1.x 系列包括了授權這一新增的安全特性,這是許多組織使用產品的重要需求。一些 Cloudera 客戶已經為大的負載使用 Impala。

Impala 1.2.0 版本目前是測試版,因為它使用了許多僅在 CDH 5.0 測試版中可用的特性。隨後的與 CDH 4 協同的 1.2.1 和 1.2.2,適用於生產環境 (相比 1.2.1,更推薦 1.2.2,因為 1.2.2 包含了許多針對連線查詢的效能優化)。

如何為 Impala 配置 Hadoop 高可用性 (HA)?

你可以設定代理伺服器,轉發 Impala 伺服器來回的請求,以實現負載均衡和高可用性。參見 Using Impala through a Proxy for High Availability 瞭解詳細資訊。

你可以為 Hive metastore 啟用 HDFS HA。參見 CDH4 High Availability Guide 瞭解詳細資訊。

Impala 出現錯誤時都發生了什麼?

Impala 中不會出現單點故障。所有的 Impala 守護程序全都可以處理所接受的查詢。假如一臺機器出現故障,在這臺機器上有查詢片段(fragments)在上面執行的查詢都會失敗。因為查詢被期望快速返回的,當查詢失敗時你可以重新執行失敗的查詢(Because queries are expected to return quickly, you can just rerun the query if there is a failure)。參見 Impala Concepts and Architecture 瞭解 Impala 架構的詳細資訊。

完整回答:Impala 必須能夠連線到 Hive metastore。Impala 積極快取元資料,這樣 metastore 主機的負載很小。Impala 依賴於 HDFS NameNode,並且在 CDH 4中你可以為 HDFS 配置 HA。Impala 同樣有一個集中的軟體狀態(soft-state)服務,稱作 statestore 和 catalog 服務,僅僅在一臺主機上執行。假如 statestore 主機下線,Impala 會繼續執行查詢,但不會獲得狀態更新。例如,如果在 statestore 主機下線期間向叢集添加了一臺主機,執行在其他主機上的已有的 impalad 例項將不會發現這臺新的主機。一當 statestore 程序重啟後,所有它提供的資訊會根據所有執行的 Impala 守護程序自動重建。

Impala 表中最多允許多少行?

沒有限制。一些使用者已經使用 Impala 查詢包含上萬億記錄的表。

Impala 和 MapReduce 作業可以在相同叢集中執行而不會資源衝突嗎?

是的。參見 Controlling Resource Usage 瞭解如何使用 Linux cgroup 機制控制 Impala 使用的資源,以及 Using YARN Resource Management with Impala (CDH 5 Only) 瞭解如何使用 Impala 和 YARN 資源管理框架。Impala 被設計為執行在 DataNode 主機上的。任何資源衝突都依賴於叢集的配置和負載。

關於詳細的如何配置叢集在 Impala 查詢和 MapReduce 作業之間共享資源的例子,參見 Setting up a Multi-tenant Cluster for Impala and MapReduce

Impala Internals

Impala 應當在哪些主機上執行?

為了更佳的效能,Cloudera 強烈推薦在每一臺資料節點(DataNode)上都執行 impalad 守護程序。儘管這一拓撲結構不是硬性要求,假如有任意主機,上面包含了資料塊副本但是沒有 Impala 守護程序執行,那麼涉及到這些資料的查詢的效率將非常低下(if there are data blocks with no Impala daemons running on any of the hosts containing replicas of those blocks, queries involving that data could be very inefficient)。這時候,這些資料必須通過"遠端讀取"從一臺主機傳輸到另外一臺主機以進行處理,這是 Impala 應儘量避免的情況。參見 Impala Concepts and Architecture 瞭解關於 Impala 架構的詳細資訊。Impala 會盡可能的排程查詢分片,以便能在存放對應資料的主機上執行查詢(Impala schedules query fragments on all hosts holding data relevant to the query, if possible)。

Impala 中連線如何執行?

預設的,Impala 使用基於成本的方法,根據表的總大小和行數,自動確定最高效的表連線順序(這是從 Impala 1.2.2 才開始具有的新特性)。使用 COMPUTE STATS 語句採集的每一個表的統計資訊是高效連線的關鍵。Impala 連線查詢在兩種連線技術之間進行選擇,分別是 "廣播連線(broadcast joins)" 和 "分割連線(partitioned joins)"。參見 Joins 瞭解語法詳情,參見 Performance Considerations for Join Queries 瞭解效能注意事項。

Impala 如何處理大表的連線查詢?

Impala 採用多種策略,允許不同大小的表和結果集進行連線。當一個大表與一個小表連線時,小表中的所有資料會傳輸到每一節點上以進行中間處理。當連線兩個大表時,其中一個表的資料被拆分成多塊,每一個節點只處理其中選中的塊。參見 Joins 瞭解連線處理的詳細資訊,Performance Considerations for Join Queries 瞭解效能注意事項,Hints 瞭解如何微調連線策略。

Impala 的聚合策略是什麼?

Impala 目前僅支援記憶體中的雜湊聚合(hash aggregation)。

Impala 元資料如何管理?

Impala 使用兩部分的元資料:Hive metastore 中的目錄資訊和 NameNode 中的檔案元資料。目前,當 impalad 需要元資料以產生查詢的執行計劃時才載入並快取元資料(this metadata is lazily populated and cached when an impaladneeds it to plan a query)

當在 Hive 中載入新資料之後,使用 REFRESH 語句更新這個表的元資料。INVALIDATE METADATA Statement 語句重新整理所有的元資料,以便 Impala 識別到 Hive 中建立的新表或其他 DDL 、DML 的修改。

在 Impala 1.2 及以上版本中,有一個單獨的 catalogd 守護程序向所有節點廣播 Impala 中 DDL 或 DML 語句導致的元資料變化,減少或避免了使用 REFRESH 和 INVALIDATE METADATA 語句的需求。

併發查詢時 NameNode 負載如何?

Impala 產生的負載與 MapReduce 產生的非常類似。Impala 在規劃階段連線 NameNode 以獲得檔案元資料(僅在接收到查詢的主機上執行)。每一個 impalad 將讀取檔案作為查詢正常處理的一部分(Every impalad will read files as part of normal processing of the query)。

為何 Impala 能實現效能提升(How does Impala achieve its performance improvements)?

這是 Impala 與其他 Hadoop 元件和相關技術在效能方面不同的主要原因(These are the main factors in the performance of Impala versus that of other Hadoop components and related technologies)。

Impala 避免使用 MapReduce。儘管 MapReduce 是一種偉大的通用並行處理模型,具有許多優點,但是它不是專為執行 SQL 設計的。Impala 在這些方面避免了 MapReduce 的低效:

  • Impala 不會把中間結果存放到硬碟上。SQL 查詢通常對映成多個包含所有中間結果集都寫入到硬碟上的 MapReduce 作業(SQL queries often map to multiple MapReduce jobs with all intermediate data sets written to disk)
  • Impala 避免了 MapReduce 啟動時間的耗費。對於互動式查詢,MapReduce 啟動時間變得非常醒目。Impala 以服務方式執行,實際上沒有啟動時間
  • Impala 可以更自然的分散查詢計劃,而不是不得不納入 map 和 reduce 作業管道中。這使得 Impala 可以並行處理查詢的多個步驟,並避免不必要的負載如排序和混洗(This enables Impala to parallelize multiple stages of a query and avoid overheads such as sort and shuffle when unnecessary)

Impala 通過利用最新機器和技術(modern hardware and technologies),採用了一種更高效的執行引擎(Impala uses a more efficient execution engine by taking advantage of modern hardware and technologies):

  • Impala 生成執行時程式碼。Impala 使用 LLVM 為要執行的查詢生成彙編碼(assembly code)。個別查詢不需要為執行在可以支援各種查詢的系統而支付代價(Individual queries do not have to pay the overhead of running on a system that needs to be able to execute arbitrary queries)
  • Impala 儘可能採用最新的硬體指令。Impala 使用最新的 SSE (SSE4.2) 指令集,某些情況下可以提供巨大的加速效果
  • Impala 採用更好的 I/O 排程。Impala 瞭解塊在硬碟上的位置,並可以排程塊處理的順序,以便保證所有硬碟都繁忙
  • Impala 專為效能設計。Impala 採取以效能為導向的設計原則,為此花費了大量的時間,例如緊密內部迴圈、行內函數呼叫、最小分支、更好的快取使用、以及最小記憶體使用等(A lot of time has been spent in designing Impala with sound performance-oriented fundamentals, such as tight inner loops, inlined function calls, minimal branching, better use of cache, and minimal memory usage)

當資料集超出可用記憶體時會發生什麼?

目前來說,假如在某一節點上處理中間結果集所需的記憶體超出了這一節點上 Impala 可用的記憶體,查詢會被取消。你可以調整每一節點上 Impala 的可用記憶體,也可以對你最大的查詢微調連線策略來減少記憶體需求。我們計劃在將來支援外部連線和排序。

但請記住,使用記憶體的大小並不是跟輸入資料集的大小直接相關。對於聚合來說,使用的記憶體跟分組後的行數有關。對於連線來說,使用的記憶體與除了最大的表之外其他所有表的大小相關,並且 Impala 可以採用在每個節點之間拆分大的連線表而不是把整個表都傳輸到每個節點的連線策略。

哪些是記憶體密集型操作?

假如查詢失敗,錯誤資訊是 "memory limit exceeded",你可能懷疑有記憶體洩露(memory leak)。其實問題可能是因為查詢構造的方式導致 Impala 分配超出你預期的記憶體,從而在某些節點上超出 Impala 分配的記憶體限制(The problem could actually be a query that is structured in a way that causes Impala to allocate more memory than you expect, exceeded the memory allocated for Impala on a particular node)。一些特別記憶體密集型的查詢和表結構如下:

  • 使用動態分割槽的 INSERT 語句,插入到包含許多分割槽的表中(特別是使用 Parquet 格式的表,這些表中每一個分割槽的資料都儲存到記憶體中,直到它達到 1 GB 並被寫入到硬盤裡)。考慮把這樣的操作分散成幾個不同的 INSERT 語句,例如一次只加載一年的資料而不是一次載入所有年份的資料
  • 在唯一或高基數(high-cardinality)列上的 GROUP BY 操作。Impala 為 GROUP BY 查詢中每一個不同的值分配一些處理結構(handler structures)。成千上萬不同的 GROUP BY 值可能超出記憶體限制
  • 查詢涉及到非常寬、包含上千個列的表,特別是包含許多 STRING 列的表。因為 Impala 允許 STRING 值最大不超過 32 KB,這些查詢的中間結果集可能需要大量的記憶體分配

何時 Impala 分配(hold on to)或釋放(return)記憶體?

Impala 使用 tcmalloc 分配記憶體,一款專為高併發優化的記憶體分頻器。一當 Impala 分配了記憶體,它保留這些記憶體用於將來的查詢。因此,空閒時顯示 Impala 有很高的記憶體使用是很正常的。假如 Impala 檢測到它將超過記憶體限制(通過 -mem_limit 啟動選項或 MEM_LIMIT 查詢選項定義),它將釋放當前查詢不需要的所有記憶體。

當通過 JDBC 或 ODBC 介面執行查詢,請確保在之後呼叫對應的關閉方法。否則,查詢關聯的一些記憶體不會釋放。

SQL

是否支援 UPDATE 語句?

Impala 目前不支援 UPDATE 語句,它通常用於修改單行資料、一小組資料、或特定的列。通常 Impala 查詢使用的基於 HDFS 的檔案針對一次超過許多M的批量操作(bulk operations)進行了優化,這使得傳統的 UPDATE 操作低效或不切實際。

你可以使用下面的技術來達到與熟悉的 UPDATE 語句相同的目標,併為之後的查詢保持高效的檔案佈局:

  • 使用你已經更新後並存放在其他位置的資料替換掉表或分割槽的全部內容,或者使用 INSERT OVERWRITE, LOAD DATA, 或者使用手工 HDFS 檔案操作之後對這個表執行 REFRESH 語句。可選的,你可以在 INSERT 語句中使用內建函式和表示式來轉換複製的資料,就像你通常在 UPDATE 語句中所做的那樣,例如轉換一個混合大小寫的字串為全部大寫或全部小寫
  • 為了更新單行資料,請使用 HBase 表,並使用與原來行相同的 key 執行 INSERT ... VALUES 語句。因為 HBase 通過只返回特定鍵值的最新的行來處理重複的鍵,新插入的行有效的隱藏了之前的

Impala 可以執行使用者定義函式(UDFs)嗎?

Impala 1.2 及以上版本支援 UDFs 和 UDAs。你可以使用 C++ 編寫本地 Impala UDFs 和 UDAs,或者重用之前用 Java 編寫的 Hive 中的 UDFs (但不支援 UDAs) 。參見 User-Defined Functions 瞭解詳細資訊。

為什麼我必須使用 REFRESH 和 INVALIDATE METADATA,它們做了什麼?

在 Impala 1.2 或更高版本中,大大減少了使用 REFRESH 和 INVALIDATE METADATA 語句的情況:

  • 新的 impala 目錄服務,即 catalogd 守護程序,向所有 Impala 節點廣播 Impala DDL 語句的結果。因此,假如你在一個 Impala 節點執行了 CREATE TABLE 語句,再通過其他節點執行查詢時,不再需要執行 INVALIDATE METADATA
  • 目錄服務只識別到通過 Impala 導致的變更,因此如果你通過 Hive,或者通過在 HDFS 中操作檔案載入資料,仍然必須使用 REFRESH 語句,並且如果你在 Hive 中建立、修改表、新增或刪除分割槽、或執行其他 DDL 操作後,必須執行 INVALIDATE METADATA 語句
  • 因為目錄服務向所有節點廣播 REFRESH 和 INVALIDATE METADATA 語句的結果,當你仍然需要執行這些語句的時候,你可以只在其中一個節點上執行,而不是在所有節點上執行,並且這些變化會被整個叢集自動識別。這使得可以通過任意 Impala 節點執行查詢而不是總使用同一個協調器節點,更方便負載均衡

為什麼執行 DROP TABLE 之後空間不釋放?

當你對內部表而不是外部表執行 DROP TABLE 後,Impala 刪除對應的資料檔案。預設的,CREATE TABLE 語句建立內部表,檔案被 Impala 管理。外部表通過 CREATE EXTERNAL TABLE 語句建立,檔案位置在 Impala 控制範圍之外。請執行 DESCRIBE FORMATTED 語句檢查表是內部表還是外部表。關鍵字 MANAGED_TABLE 表示是內部表,Impala 可以刪除這些資料檔案。關鍵字 EXTERNAL_TABLE 表示這是外部表,當你刪除表時,Impala 將保持這些資料檔案不變。

即使當你刪除一個內部表並且檔案已經從原來的位置移除,你可能也不會立刻得到空閒的硬碟空間。預設的,HDFS 中刪除的檔案放到特定的回收站(trashcan)目錄,在那裡過一段時間(預設是 6 小時)後被清除。關於回收站機制的背景知識,請參見 http://archive.cloudera.com/cdh4/cdh/4/hadoop/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html。更多關於在回收站清除檔案的資訊,參見 http://archive.cloudera.com/cdh4/cdh/4/hadoop/hadoop-project-dist/hadoop-common/FileSystemShell.html

當 Impala 刪除檔案,並且那些檔案被移動到 HDFS 回收站,他們存放在屬於 impala 使用者的 HDFS 目錄中。假如 impala 使用者沒有 HDFS home 目錄,在這裡回收站會被建立,基於安全的考慮,這些檔案不會被刪除和移動。假如你執行了 DROP TABLE 語句,然後發現表的資料檔案仍然在原來的位置,請先建立 HDFS 目錄 /user/impala,屬於 impala 使用者,並可寫。例如,你可能發現 /user/impala 屬於 hdfs 使用者,這時你需要切換成 hdfs 使用者並執行類似的命令:

hdfs dfs -chown -R impala /user/impala

Partitioned Tables

我怎麼把一個大的 CSV 檔案載入到分割槽表裡?

為了向分割槽表裡載入資料檔案,當資料檔案包含類似 year,month, 等等對應著分割槽鍵的列時,使用兩步處理。首先,使用 LOAD DATA 或 CREATE EXTERNAL TABLE 語句載入資料到未分割槽的表裡。然後使用 INSERT ... SELECT 語句從未分割槽的表向分割槽表複製資料。在 INSERT 語句中包含 PARTITION 子句指定分割槽鍵列。對每一個分割槽,這一 INSERT 操作把資料拆分成單獨的資料檔案。例如,參見 Partitioning 中的例子。關於如何把資料載入到分割槽 Parquet 表(大批量資料的熱門選擇)的詳細資訊,參見 Loading Data into Parquet Tables

我可以執行 INSERT ... SELECT *載入資料到分割槽表嗎?

當你使用 INSERT ... SELECT * 語法複製資料到分割槽表時,對應分割槽鍵的列必須出現在 SELECT * 所返回列的最後。你可以把分割槽鍵定義放在最後來建立表。或者,你可以使用 CREATE VIEW 語句建立一個記錄這些列:把分割槽鍵列放在最後,然後使用 INSERT ... SELECT * from the view。