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();
}
}