概述
Impala可以直接在存儲在HDFS,HBase或Amazon Simple Storage Service(S3)中的Apache Hadoop數據上提供快速,交互式的SQL查詢。 除了使用相同的統一存儲平台,Impala和Apache Hive一樣還使用相同的元數據,SQL語法(Hive SQL),ODBC驅動程序和用戶界面(Hue中的Impala查詢UI)。
Impala是用於查詢大數據的工具的補充。 Impala不會替代基於MapReduce的批處理框架,如Hive。 基於MapReduce的Hive和其他框架最適用於長時間運行的批處理作業,例如涉及批處理Extract,Transform和Load(ETL)類型作業的工作。
1 impala特點
1.1 優點
- 基於內存進行計算,能夠對PB級別的數據進行實時交互查詢、分析
- C ++ 編寫,LLVM(C++的一種編譯器)統一編譯,效率高
- 支持Data local 效率高
- 兼容HiveSQL
- 具有數據倉庫的特性,可對hive數據直接做數據分析
- 支持列式存儲(可以和hbase整合)
- 支持JDBC/ODBC遠程訪問
1.2 缺點
- 對內存依賴大
- 完全依賴於hive
- 實踐過程中 分區超過1w 性能嚴重下下降
- 穩定性不如hive
2 體系架構
Impala的系統架構如上圖所示,Impala使用了Hive的SQL接口(包括SELECT、INSERT、JOIN等操作),表的元數據信息存儲在Hive Metastore中。StateStore是Impala的一個子服務,用於監控集群中各個節點的健康狀況,提供節點注冊、錯誤檢測等功能;Impala在每個節點運行了一個后台服務Impalad,用於響應外部請求,並完成實際的查詢處理。Impalad主要包含Query Planner、Query Coordinator和Query Exec Engine三個模塊。Query Planner接收來自SQL APP和ODBC的查詢,然后將查詢轉換為許多子查詢,Query Coordinator將這些子查詢分發到各個節點上,由各個節點上的Query Exec Engine負責子查詢的執行,然后返回子查詢的結果,這些中間結果經過聚集之后最終返回給用戶。
3 安裝方式
3.1 使用cloudera manager 進行安裝
3.2 手動安裝
4 核心組件
4.1 Statestore Daemon
該進程負責搜集集群中Impalad進程節點的健康狀況,它通過創建多個線程來處理Impalad的注冊訂閱,並與各節點保持心跳連接,不斷地將健康狀況的結果轉發給所有的Impalad進程節點。一個Impala集群只需一個statestored進程節點,當某一節點不可用時,該進程負責將這一信息傳遞給所有的Impalad進程節點,再有新的查詢時不會把請求發送到不可用的節點上。
4.2 Catalog Daemon
Impala目錄服務組件將Impala SQL語句產生的元數據更改通知到群集中的所有DataNodes上。避免了通過Impala發出的SQL語句執行時產生的元數據更改,需要發出REFRESH和INVALIDATE METADATA語句才能生效。當您通過Hive創建表,加載數據等時,您需要在Impala節點上執行REFRESH或INVALIDATE METADATA,然后才能執行查詢。
4.3 Impala Daemon
它是運行在集群每個節點上的守護進程,是Impala的核心組件,在每個節點上這個進程的名稱為Impalad。該進程負責讀寫數據文件;接受來自Impala-shell、Hue、JDBC、ODBC等客戶端的查詢請求(接收查詢請求的Impalad為Coordinator),Coordinator通過JNI調用java前端解釋SQL查詢語句,生成查詢計划樹,再通過調度器把執行計划分發給具有相應數據的其它節點分布式並行執行,並將各節點的查詢結果返回給中心協調者節點Coordinator,再由該節點返回給客戶端。同時Impalad會與State Store保持通信,以了解其他節點的健康狀況和負載。
4.4 Impala Shell
提供給用戶查詢使用的命令行交互工具,供使用者發起數據查詢或管理任務,同時Impala還提供了Hue、JDBC、ODBC等使用接口。
5 impala CDH優化
- impala daemon 內存限制
- StateStore 工作線程數
6 impala-shell 用法
-h (--help) 幫助
-v (--version) 查詢版本信息-V(--verbose) 啟用詳細輸出
--quiet 關閉詳細輸出
-p 顯示執行計划
-i hostname(--impalad=hostname) 指定連接主機 格式hostname:port 默認端口21000
-r(--refresh_after_connect)刷新所有元數據
-q query(--query=query) 從命令行執行查詢,不進入impala-shell
-d default_db(--database=default_db) 指定數據庫
-B(--delimited)去格式化輸出
--output_delimiter=character 指定分隔符
--print_header 打印列名
-f query_file(--query_file=query_file)執行查詢文件,以分號分隔
-o filename(--output_file filename) 結果輸出到指定文件
-c 查詢執行失敗時繼續執行
-k(--kerberos) 使用kerberos安全加密方式運行impala-shell
-l 啟用LDAP認證
-u 啟用LDAP時,指定用戶名Impala Shell
進入impala-shell后的特殊用法:
help
connect <hostname:port> 連接主機,默認端口21000
refresh <tablename> 增量刷新元數據庫
invalidate metadata 全量刷新元數據庫
explain <sql> 顯示查詢執行計划、步驟信息
set explain_level 設置顯示級別( 0,1,2,3)
shell <shell> 不退出impala-shell執行Linux命令
profile (查詢完成后執行) 查詢最近一次查詢的底層信息
7 impala監控管理
7.1 查看StateStore
7.2 查看Catalog
8 impala存儲
8.1 文件類型
8.2 壓縮方式
9 impala分區
9.1 創建分區方式
- partitioned by 創建表時,添加該字段指定分區列表
create table t_person(id int, name string, age int) partitioned by (type string);
- 使用alter table 進行分區的添加和刪除操作
alter table t_person add partition (sex=‘man');
alter table t_person drop partition (sex=‘man');
alter table t_person drop partition (sex=‘man‘,type=‘boss’);
9.2 分區內添加數據
insert into t_person partition (type='boss') values (1,’zhangsan’,18),(2,’lisi’,23)
insert into t_person partition (type='coder') values (3,wangwu’,22),(4,’zhaoliu’,28),(5,’tianqi’,24)
9.3 查詢指定分區
select id,name from t_person where type=‘coder’
10 hive 和impala區別
10.1 數據類型
- impala支持數據類型沒有hive多
10.2 不支持HiveQL以下特性
- 可擴展機制
- xml json函數
- 聚合函數
- 多distinct查詢
11 常用sql
-- 創建數據庫
create database db1;
-- 使用數據庫
use db1;
-- 刪除數據庫
drop database db1;
-- 創建外部表
CREATE TABLE table01 (
id INT,
name STRING,
confirm_flag INT,
create_date TIMESTAMP,
create_user_id STRING,
id BIGINT,
license_num STRING,
NAME STRING,
postcode STRING,
update_date TIMESTAMP,
update_user_id STRING,
valid_flag INT
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' WITH SERDEPROPERTIES (
'serialization.format' = '|',
'field.delim' = '|'
) STORED AS Parquet LOCATION 'hdfs://node03:8020/user/hive/warehouse/table01';
-- 使用現有表進行創建
create table tab_3 like tab_1;
-- 創建內部表
CREATE TABLE table01 (
id INT,
name STRING,
confirm_flag INT,
create_date TIMESTAMP,
create_user_id STRING,
id BIGINT,
license_num STRING,
NAME STRING,
postcode STRING,
update_date TIMESTAMP,
update_user_id STRING,
valid_flag INT
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' WITH SERDEPROPERTIES (
'serialization.format' = '|',
'field.delim' = '|'
) STORED AS Parquet LOCATION 'hdfs://node03:8020/test/table01';
-- 創建視圖
create view v1 as select count(id) as total from tab_3 ;
-- 查詢視圖
select * from v1;
-- 查看視圖定義
describe formatted v1
-- 數據導入
* 加載數據:
insert語句:插入數據時每條數據產生一個數據文件,不建議用此方式
* 加載批量數據
load data方式:在進行批量插入時使用這種方式比較合適
來自中間表:此種方式使用於從一個小文件較多的大表中讀取文件並寫
入新的表生產少量的數據文件。也可以通過此種方式進行格式轉換。
* 空值處理:
impala將“\n” 表示為NULL,在結合sqoop使用是注意做相應的空字段
過濾,
也可以使用以下方式進行處理:
alter table name set tblproperties
(“serialization.null.format”=“null”)
-- 示例
CREATE TABLE access_log_text (
log_id BIGINT,
idc_id STRING,
house_id BIGINT,
src_port BIGINT,
dest_port BIGINT,
protocol_type INT,
access_time STRING ,
src_ip_long BIGINT,
dest_ip_long BIGINT,
url64 STRING
) PARTITIONED BY (hn BIGINT,ds STRING) ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|'
STORED AS TEXTFILE;
alter table access_log_text add partition(hn=91014,ds='2017-05-18-11');
insert into access_log_text partition(hn=91014,ds='2017-05-18-11') values(12345,"A2.B1.B2-20090003",91014,53487,80,1,"2017-05-18 11:00:19",2076024904,2086642602,"aHR0cDovL3d4MS5zaW5haW1nLmNuL3RodW1iMTUwLzY5MjdlN2E1bHkxZmVkdnU4ejkxNmoyMGM4MGVzM3prLmpwZw==");
--內部表,parquet格式存儲
CREATE TABLE access_log_parquet (
log_id BIGINT,
idc_id STRING,
house_id BIGINT,
src_port BIGINT,
dest_port BIGINT,
protocol_type INT,
access_time STRING ,
src_ip_long BIGINT,
dest_ip_long BIGINT,
url64 STRING
) PARTITIONED BY (hn BIGINT,ds STRING) STORED AS PARQUET;
alter table access_log_parquet add partition(hn=91014,ds='2017-05-18-11');
alter table access_log_parquet add partition(hn=91014,ds='2017-05-18-12');
insert into access_log_parquet partition(hn=91014,ds='2017-05-18-11') values(12345,"A2.B1.B2-20090003",91014,53487,80,1,"2017-05-18 11:00:19",2076024904,2086642602,"aHR0cDovL3d4MS5zaW5haW1nLmNuL3RodW1iMTUwLzY5MjdlN2E1bHkxZmVkdnU4ejkxNmoyMGM4MGVzM3prLmpwZw==");
insert into access_log_parquet partition(hn=91014,ds='2017-05-18-12') select log_id,idc_id,house_id,src_port,dest_port,protocol_type,access_time,src_ip_long,dest_ip_long,url64 from access_log_text where hn=91014 and ds='2017-05-18-11';
--覆蓋更新
insert overwrite table access_log_parquet (log_id,idc_id,house_id,src_port,dest_port,protocol_type,access_time,src_ip_long,dest_ip_long,url64) partition (hn=91014, ds = '2017-05-18-13' ) select log_id,idc_id,house_id,src_port,dest_port,protocol_type,access_time,src_ip_long,dest_ip_long,url64 from access_log_parquet where hn=91014 and ds='2017-05-18-11';
--load data inpath
load data inpath '/input/access/12345.txt' into table access_log_text partition (hn=91014,ds='2017-05-18-11');
--文件拷貝
需要刷新元數據
外部表
CREATE EXTERNAL TABLE access_log_parquet_external (
log_id BIGINT,
idc_id STRING,
house_id BIGINT,
src_port BIGINT,
dest_port BIGINT,
protocol_type INT,
access_time STRING ,
src_ip_long BIGINT,
dest_ip_long BIGINT,
url64 STRING
) PARTITIONED BY (hn BIGINT,ds STRING) STORED AS PARQUET LOCATION '/user/hive/warehouse/access_log_parquet_external ';
alter table access_log_parquet_external add partition(hn=91014,ds='2017-05-17-11');