Impala是什么:
Impala是Cloudera提供的⼀款開源的針對HDFS和HBASE中的PB級別數據進⾏交互式實時查詢(Impala 速度快),Impala是參照⾕歌的新三篇論⽂當中的Dremel實現⽽來,其中舊三篇論⽂分別是 (BigTable,GFS,MapReduce)分別對應我們即將學的HBase和已經學過的HDFS以及MapReduce。
Impala最⼤賣點和最⼤特點就是快速,Impala中⽂翻譯是⾼⻆羚⽺。
Impala優勢:
之前學習的Hive以及MR適合離線批處理,但是對交互式查詢的場景⽆能為⼒(要求快速響應),所以為了 解決查詢速度的問題,Cloudera公司依據Google的Dremel開發了Impala,Impala拋棄了MapReduce 使⽤了類似於傳統的MPP數據庫技術,⼤⼤提⾼了查詢的速度。
MPP是什么?
MPP (Massively Parallel Processing),就是⼤規模並⾏處理,在MPP集群中,每個節點資源都是獨⽴ 享有也就是有獨⽴的磁盤和內存,每個節點通過⽹絡互相連接,彼此協同計算,作為整體提供數據服 務。
Impala 優勢:
- Impala沒有采取MapReduce作為計算引擎,MR是⾮常好的分布式並⾏計算框架,但MR引擎更多 的是⾯向批處理模式,⽽不是⾯向交互式的SQL執⾏。與 Hive相⽐:Impala把整個查詢任務轉為 ⼀棵執⾏計划樹,⽽不是⼀連串的MR任務,在分發執⾏計划后,Impala使⽤拉取的⽅式獲取上個 階段的執⾏結果,把結果數據、按執⾏樹流式傳遞匯集,減少的了把中間結果寫⼊磁盤的步驟,再 從磁盤讀取數據的開銷。Impala使⽤服務的⽅式避免 每次執⾏查詢都需要啟動的開銷,即相⽐ Hive沒了MR啟動時間。
- 使⽤LLVM(C++編寫的編譯器)產⽣運⾏代碼,針對特定查詢⽣成特定代碼。
- 優秀的IO調度,Impala⽀持直接數據塊讀取和本地代碼計算。
- 選擇適合的數據存儲格式可以得到最好的性能(Impala⽀持多種存儲格式)。
- 盡可能使⽤內存,中間結果不寫磁盤,及時通過⽹絡以stream的⽅式傳遞。
Impala與Hive對⽐分析:
查詢過程
- Hive:在Hive中,每個查詢都有⼀個“冷啟動”的常⻅問題。(map,reduce每次都要啟動關閉,申 請資源,釋放資源。。。)
- Impala:Impala避免了任何可能的啟動開銷,這是⼀種本地查詢語⾔。 因為要始終處理查詢,則 Impala守護程序進程總是在集群啟動之后就准備就緒。守護進程在集群啟動之后可以接收查詢任 務並執⾏查詢任務。
中間結果
- Hive:Hive通過MR引擎實現所有中間結果,中間結果需要落盤,這對降低數據處理速度有不利影 響。
- Impala:在執⾏程序之間使⽤流的⽅式傳輸中間結果,避免數據落盤。盡可能使⽤內存避免磁盤 開銷
交互查詢
- Hive:對於交互式計算,Hive不是理想的選擇。
- Impala:對於交互式計算,Impala⾮常適合。(數據量級PB級)
計算引擎
- Hive:是基於批處理的Hadoop MapReduce
- Impala:更像是MPP數據庫
容錯
- Hive:Hive是容錯的(通過MR&Yarn實現)
- Impala:Impala沒有容錯,由於良好的查詢性能,Impala遇到錯誤會重新執⾏⼀次查詢
查詢速度
- Impala:Impala⽐Hive快3-90倍。
Impala優勢總結
- 1. Impala最⼤優點就是查詢速度快,在⼀定數據量下;
- 2. 速度快的原因:避免了MR引擎的弊端,采⽤了MPP數據庫技術
元數據更新:
因為impala 不能自動感知 hive對元數據的更新操作。
- 更新所有元數據,⼿動執⾏invalidate metadata;
- 更新某一個表的元數據,refresh dbname.tablename
impala架構圖:
如果是大表join ,impala使用hash join,使得hash 值一樣的 id去往同一節點,這樣不同節點可以並行執行join操作。
如果是小表,impala使用 廣播 join。
group by 操作: impala 會對分組字段進行hash 分發,這樣不同節點可以並行執行局部group by 操作,最終merge所有節點的結果。
jdbc連接 impala:
impala的sql語法與hive基本一樣,支持大部分的hive內置函數。
impala的命令行是impala-shell
關於impala的相關配置參考word 文檔。
<dependencies> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoopcommon --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.9.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-common -- > <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-common</artifactId> <version>2.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-metastore --> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-metastore</artifactId> <version>2.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-service - -> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-service</artifactId> <version>2.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc --> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>2.3.7</version> <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec --> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>2.3.7</version> </dependency> </dependencies>
package com.lagou.impala.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class ImpalaTest { public static void main(String[] args) throws Exception { //定義連接impala的驅動和連接url String driver = "org.apache.hive.jdbc.HiveDriver"; String driverUrl = "jdbc:hive2://linux122:21050/default;auth=noSasl"; //查詢的sql語句 String querySql = "select * from t1"; //獲取連接 Class.forName(driver); //通過Drivermanager獲取連接 final Connection connection = DriverManager.getConnection(driverUrl); final PreparedStatement ps = connection.prepareStatement(querySql); //執⾏查詢 final ResultSet resultSet = ps.executeQuery(); //解析返回結果 //獲取到每條數據的列數 final int columnCount = resultSet.getMetaData().getColumnCount(); //遍歷結果集 while (resultSet.next()) { for (int i = 1; i <= columnCount; i++) { final String string = resultSet.getString(i); System.out.print(string + "\t"); } System.out.println(); } //關閉資源 ps.close(); connection.close(); } }