Impala是基于MPP架構(gòu)的查詢引擎。
什么是MPP?
做業(yè)務(wù)的同學(xué)應(yīng)該比較熟悉,當(dāng)一張表數(shù)據(jù)過大時,通常會考慮分庫分表。一種常見的方式是縱向拆分。以某個字段的hash值為key,經(jīng)過一致性hash算法,命中到不同庫中。每個庫之間不共享數(shù)據(jù),可獨立運算。這可以說是MPP的雛形。
MPP 即大規(guī)模并行處理(Massively Parallel Processor )。 在數(shù)據(jù)庫非共享集群中,每個節(jié)點都有獨立的磁盤存儲系統(tǒng)和內(nèi)存系統(tǒng),業(yè)務(wù)數(shù)據(jù)根據(jù)數(shù)據(jù)庫模型和應(yīng)用特點劃分到各個節(jié)點上,每臺數(shù)據(jù)節(jié)點通過專用網(wǎng)絡(luò)或者商業(yè)通用網(wǎng)絡(luò)互相連接,彼此協(xié)同計算,作為整體提供數(shù)據(jù) 庫服務(wù)。非共享數(shù)據(jù)庫集群有完全的可伸縮性、高可用、高性能、優(yōu)秀的性價比、資源共享等優(yōu)勢。
例子
Greenplum 即是MPP架構(gòu)的數(shù)據(jù)庫,底層基于PostgreSQL,主機、操作系統(tǒng)、內(nèi)存和存儲都是自我控制的,不存在共享,每個節(jié)點都是一個單獨的數(shù)據(jù)庫。節(jié)點之間的信息交互是通過節(jié)點互聯(lián)網(wǎng)絡(luò)實現(xiàn)。通過將數(shù)據(jù)分布到多個節(jié)點上來實現(xiàn)規(guī)模數(shù)據(jù)的存儲,通過并行查詢處理來提高查詢性能。
優(yōu)缺點(相比hadoop)
注意:這里說的是MPP架構(gòu)的數(shù)據(jù)庫和于hadoop對比,Impala是 MPP-OVER-HADOOP的查詢引擎,并非類似GP的數(shù)據(jù)庫。)
為什么要聊MPP數(shù)據(jù)庫,因為MPP數(shù)據(jù)庫的特點基本等于MPP查詢引擎的特點。
-
優(yōu)點
基于關(guān)系型數(shù)據(jù)庫,每個節(jié)點獨立存儲和計算,所以查詢時延低。簡單易用,DBA即可維護。 - 缺點
- 集群擴展性差(相比HDFS),一般認為節(jié)點上限是百級(小于等于200)。
- 可處理數(shù)據(jù)上限相比hadoop較小。
- MPP架構(gòu)數(shù)據(jù)庫一般是商業(yè)解決方案,相比hadoop可用廉價PC搭建集群,MPP價格較高。
- 單節(jié)點故障會導(dǎo)致整個作業(yè)失敗。
Impala核心組件
impalad
集群上每個DataNode部署了一個impala daemon,進程名為impalad。它可以讀寫數(shù)據(jù)文件,接受JDBC或shell發(fā)出的查詢命令,并行化查詢并在整個集群中分配工作,將中間查詢結(jié)果發(fā)送回coordinator節(jié)點。
每個impalad都可以作為coordinator。執(zhí)行查詢時impala默認會以Round Robin的方式選舉一個。shell腳本提交時可能使用同一個coordinator。2.9以上的版本可以指定coordinator。
impalad 與 StateStore 不斷通信,監(jiān)控impalad的健康狀況,并確定哪些節(jié)點可以接收新工作。當(dāng)任何節(jié)點做 create,alter,drop,insert,load data操作時,impalad 從 catalogd 接受廣播消息,這樣可以減少 REFRESH 和 INVALIDATE METADATA 的調(diào)用。
coordinator
coordinator相當(dāng)于中央?yún)f(xié)調(diào)器。負責(zé)調(diào)度、監(jiān)控任務(wù)執(zhí)行狀態(tài),對結(jié)果做最后的匯總計算。從impalad中指定(或分配)產(chǎn)生。
StateStore
StateStore是一個基于C/S的發(fā)布/訂閱服務(wù)。通過心跳監(jiān)測每個impalad的健康狀況,集群中只有一個StateStore,進程名statestored。
當(dāng)某個impalad異常時,StateStore通知其他impalad不再發(fā)送查詢到該節(jié)點。在出現(xiàn)一些未知情況時,StateStore可以向coordinator廣播元數(shù)據(jù)。
StateStore是非必需的,即使StateStore異?;蛘呶磫?,依然可以執(zhí)行查詢。只是某個impalad異常時無法通知其他impalad,元數(shù)據(jù)可能會不一致。
如果在StateStore關(guān)閉時發(fā)送了DDL語句,則訪問DDL創(chuàng)建的新對象的查詢將失敗。
catalog
catalog也是一個集群中只有一個的守護進程:名為catalogd。通常將其啟動在和SateStore進程的同一節(jié)點上,因為catalog的請求是通過statestore轉(zhuǎn)發(fā),在同一節(jié)點可以節(jié)約網(wǎng)絡(luò)開銷。
簡單來說catalogd作用就是同步元數(shù)據(jù)到所有impalad。當(dāng)通過impala執(zhí)行DDL或insert操作時,catalogd會自動同步元數(shù)據(jù)。但是當(dāng)通過hive操作表時,需要在impalad執(zhí)行REFRESH和INVALIDATE METADATA手動同步元數(shù)據(jù)到impala。
Impala 查詢過程

名詞解釋
-
catalogd:impala系統(tǒng)中的元數(shù)據(jù)服務(wù)節(jié)點 -
statestored:impala系統(tǒng)中的消息同步節(jié)點 -
impalad:impala系統(tǒng)中的任務(wù)執(zhí)行節(jié)點 -
coordinator:impalad節(jié)點中的調(diào)度模塊,對外提供查詢接口,包括beeswax和HiveServer2接口 -
backend:impalad節(jié)點中任務(wù)執(zhí)行模塊,提供執(zhí)行任務(wù)的接口 -
FE:impalad代碼上劃分的frontend部分,使用JAVA實現(xiàn) -
BE:impalad代碼上劃分的backend部分,使用C++實現(xiàn) -
beeswax接口:impalad提供的一種SQL查詢接口。 -
HiveServer2接口:impalad提供的一種兼容HiveServer2的接口。 -
Analyser:Impala FE中實現(xiàn)的SQL解析器。 -
Planner:Impala FE中實現(xiàn)的SQL執(zhí)行計劃生成器。 -
PlanNode:SQL解析得到的邏輯執(zhí)行計劃中的節(jié)點基類,具體類型包括ScanNode、AggregationNode、HashJoinNode等。 -
Fragment:SQL生成的分布式執(zhí)行計劃中的一個子任務(wù),它包括執(zhí)行計劃的一個子樹。 -
ExchangeNode:比較特殊的一種PlanNode,處理前一個Fragment傳遞過來的數(shù)據(jù)。 -
DataStreamSink:它不是PlanNode,用于傳輸當(dāng)前Fragment輸出數(shù)據(jù)到不同的節(jié)點。
- 客戶端提交任務(wù):客戶端通過beeswax或者HiveServer2接口發(fā)送一個SQL查詢請求到impalad節(jié)點,查詢包括一條SQL和相關(guān)的configuration信息(只對本次查詢生效),查詢接口提供同步和異步的方式執(zhí)行,兩種接口都會返回一個queryId用于之后的客戶端操作。
- 查詢解析和分析:SQL提交到impalad節(jié)點之后交由FE模塊處理,由Analyser依次執(zhí)行SQL的詞法分析、語法分析、語義分析、查詢重寫等操作,生成該SQL的Statement信息。
- 單機執(zhí)行計劃生成:根據(jù)上一步生成的Statement信息,由Planner生成單機的執(zhí)行計劃,該執(zhí)行計劃是有PlanNode組成的一棵樹,這個過程中也會執(zhí)行一些SQL優(yōu)化,例如Join順序改變、謂詞下推等。
- 分布式執(zhí)行計劃生成:由Planner將單機執(zhí)行計劃轉(zhuǎn)換成分布式并行物理執(zhí)行計劃,物理執(zhí)行計劃由一個個的Fragment組成,F(xiàn)ragment之間有數(shù)據(jù)依賴關(guān)系,處理過程中需要在原有的執(zhí)行計劃之上加入一些ExchangeNode和DataStreamSink信息等。
- 任務(wù)調(diào)度和分發(fā):由BE處理生成的分布式物理執(zhí)行計劃,將Fragment根據(jù)數(shù)據(jù)分區(qū)信息發(fā)配到不同的Impalad節(jié)點上執(zhí)行。Impalad節(jié)點接收到執(zhí)行Fragment請求交由Backend模塊處理Fragment的執(zhí)行。
- 子任務(wù)執(zhí)行:每一個Fragment的執(zhí)行輸出通過DataStreamSink發(fā)送到下一個Fragment,由下一個Fragment的ExchangeNode接收,F(xiàn)ragment運行過程中不斷向coordinator節(jié)點匯報當(dāng)前運行狀態(tài)。
- 結(jié)果匯總:查詢的SQL通常情況下需要有一個單獨的Fragment用于結(jié)果的匯總,它只在coordinator節(jié)點運行,將多個backend的最終執(zhí)行結(jié)果匯總,轉(zhuǎn)換成ResultSet信息。
- 客戶端查詢結(jié)果:客戶端調(diào)用獲取ResultSet的接口,讀取查詢結(jié)果。
- 關(guān)閉查詢:客戶端調(diào)用CloseOperation關(guān)閉本次查詢,標志著本次查詢的結(jié)束。
以一個例子說明查詢過程:
SELECT t1.custid,SUM(t2.revenue) AS revenue FROM LargeHDFSTB1 JOIN LargeHDFSTB2 t2 on (t2.id = t1.id1)
JOIN SmallHbaseTable t3 on t3.id = t2.id2
WHERE t3.category = "Online"
group by t1.custid ORDER BY revenue DESC LIMIT 10
其對應(yīng)的單節(jié)點計劃操作符如圖所示:

從上圖可以看出,其執(zhí)行計劃首先對t1 和 t2 表的數(shù)據(jù)進行掃描,之后對掃描結(jié)果執(zhí)行Join操作,然后與t3進行Join操作,針對
GROUP BY有對應(yīng)的聚合操作,最后是針對ORDER BY ···LIMIT的TopN操作,之后可得出最終的查詢結(jié)果。
并行化操作過程如上圖所示,操作符樹被分割成6個計劃片段,除了在coordinator執(zhí)行的Top 片段非并行執(zhí)行外,其他計劃片段都是并行執(zhí)行的。同時如上圖所示,t1和t2表的join操作選擇了Shuffle Join 模式,因為這兩個表都是大表,之后和t3表的join選擇了Broadcast Join,因為t3是個小表。對于聚合操作,則分為首先局部聚合,然后全局聚合全局聚合。相應(yīng)地,Top操作也是先執(zhí)行本地Top,然后在coordinator 執(zhí)行全局Top。這樣就完成了coordinator可以并發(fā)分配的計劃片段,交由其他有關(guān)的impalad來執(zhí)行。
Impala為什么這么快?
Impala自稱數(shù)據(jù)查詢效率比Hive快幾倍甚至數(shù)十倍,它之所以這么快的原因大致有以下幾點:
- 真正的MPP查詢引擎。
- 使用C++開發(fā)而不是Java,降低運行負荷。
- 運行時代碼生成(LLVM IR),提高效率。

全新的執(zhí)行引擎(不是Mapreduce)。
在執(zhí)行SQL語句時,Impala不會把中間數(shù)據(jù)寫入到磁盤,而是在內(nèi)存中完成了所有的處理。
使用Impala的時候,查詢?nèi)蝿?wù)會馬上執(zhí)行而不是生產(chǎn)Mapreduce任務(wù),這會節(jié)約大量的初始化時間。
Impala查詢計劃解析器使用更智能的算法在多節(jié)點上分布式執(zhí)行各個查詢步驟,同時避免了sorting和shuffle這兩個非常耗時的階段,這兩個階段往往是不需要的。
Impala擁有HDFS上面各個data block的信息,當(dāng)它處理查詢的時候能夠在各個datanode上面更均衡的分發(fā)查詢。
另外一個關(guān)鍵原因是,Impala為每個查詢產(chǎn)生匯編級的代碼,當(dāng)Impala在本地內(nèi)存中運行的時候,這些匯編代碼執(zhí)行效率比其它任何代碼框架都更快,因為代碼框架會增加額外的延遲。
Impala的缺點
- catalogd和statestored都是單點服務(wù)。如果Catalogd掛掉,元數(shù)據(jù)更新就不會同步到整個impala節(jié)點。Statestored掛掉,對于更新也不會同步,只會保掛掉之前的信息。
- web信息(Impala每個組件都會提供web端,可以查看集群節(jié)點、Catalog信息、內(nèi)存信息、Query信息)不持久,顯示的信息都是存在歷史信息中,如果impala重啟后信息就會消失。
- 通過hive操作Metastore需要手動同步Impala。
- 底層存儲不能區(qū)分用戶。
- MPP架構(gòu)要求節(jié)點配置均衡,否則最慢的節(jié)點會拖慢整個執(zhí)行速度。
主流查詢引擎性能對比
Impala 和 Hive 的關(guān)系
Impala sql 和 Hive sql高度重合,基本可以無縫移植。
在1.2以上的版本,Impala也支持自定義UDF函數(shù)。
Impala可以使用 Hive的Metastore,只要數(shù)據(jù)格式是Impala支持的類型。
Impala的查詢優(yōu)化器還可以使用hive的統(tǒng)計信息。Hive的ANALYZE TABLE搜集了該信息。在1.22及更高版本,建議使用。
Impala的COMPUTE STATS語句,更可靠而且不需要在impala-shell和hive-shell之間切換。
Impala支持的文件格式
| File Type | Format | Compression Codecs | Impala Can CREATE? | Impala Can INSERT? |
|---|---|---|---|---|
| Parquet | Structured | Snappy, gzip; currently Snappy by default | Yes. | Yes: CREATE TABLE, INSERT, LOAD DATA, and query. |
| ORC | Structured | gzip, Snappy, LZO, LZ4; currently gzip by default | Experimental support in Impala 3.1.0 and higher. | No. Import data by using LOAD DATA on data files already in the right format, or use INSERT in Hive followed by REFRESH table_name in Impala. |
| Text | Unstructured | LZO, gzip, bzip2, Snappy | Yes. For CREATE TABLE with no STORED AS clause, the default file format is uncompressed text, with values separated by ASCII 0x01 characters (typically represented as Ctrl-A). |
Yes: CREATE TABLE, INSERT, LOAD DATA, and query. If LZO compression is used, you must create the table and load data in Hive. If other kinds of compression are used, you must load data through LOAD DATA, Hive, or manually in HDFS. |
| Avro | Structured | Snappy, gzip, deflate, bzip2 | Yes, in Impala 1.4.0 and higher. In lower versions, create the table using Hive. | No. Import data by using LOAD DATA on data files already in the right format, or use INSERT in Hive followed by REFRESH table_name in Impala. |
| RCFile | Structured | Snappy, gzip, deflate, bzip2 | Yes. | No. Import data by using LOAD DATA on data files already in the right format, or use INSERT in Hive followed by REFRESH table_name in Impala. |
| SequenceFile | Structured | Snappy, gzip, deflate, bzip2 | Yes. | No. Import data by using LOAD DATA on data files already in the right format, or use INSERT in Hive followed by REFRESH table_name in Impala. |
Impala性能優(yōu)化(使用方向)
- 建議使用Parquet文件格式。性能最高。
- 在可行的前提下使用Snappy壓縮。
- 能作為number類型的數(shù)據(jù)首選數(shù)值型(而非string)。比如對于年月日之類的數(shù)據(jù)。原因是number類型以二進制存儲時更節(jié)約空間,且在執(zhí)行查詢是節(jié)省內(nèi)存,尤其是資源密集型查詢。
- 分區(qū),但是不要過度分區(qū)。
- 始終在加載數(shù)據(jù)后計算統(tǒng)計數(shù)據(jù)。這樣做是為了使用Metastore的統(tǒng)計信息,更好的執(zhí)行查詢計劃。
- 使用
EXPLAIN和SUMMARY驗證合理的執(zhí)行計劃。