一、文件存儲格式
File Formats and Compression: RCFile, Avro, ORC, Parquet; Compression, LZO
1.1 textfile
1、textfile是hive默認的數據文件存儲格式
2、textfile是普通的文件文本存儲
3、不壓縮
4、可以配合壓縮配置屬性進行壓縮
CREATE TABLE `u4`(
`id` int,
`name` string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
stored as textfile;
set mapreduce.output.fileoutputformat.compress=true;
set hive.exec.compress.output=true;
insert into table u4
select * from u2;
1.2 sequencefile
1、sequencefile是hive爲用戶提供的二進制存儲
2、sequencefile不能使用load方式直接加載數據
3、本身壓縮
CREATE TABLE `u4`(
`id` int,
`name` string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
stored as sequencefile;
1.3 rcfile
1、rcfile是hive爲用戶提供的行列混合存儲
2、rcfile格式下,將會盡量把附近的行和列的塊儘量存儲到一起
3、本身壓縮,且查詢效率較高
CREATE TABLE `u5`(
`id` int,
`name` string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
stored as rcfile;
1.4 orc
1、orc是優化後的rcfile
CREATE TABLE `u6`(
`id` int,
`name` string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
stored as orc;
1.5 parquet
1、parquet是典型列式存儲,自帶壓縮,查詢較快(按列查詢)
CREATE TABLE `u7`(
`id` int,
`name` string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
stored as PARQUET;
insert into table u7
select * from u2;
1.6 自定義存儲格式
數據:
seq_yd元數據文件:
aGVsbG8gemhhbmdoYW8=
aGVsbG8gZmVpZmVpLGdvb2QgZ29vZCBzdHVkeSxkYXkgZGF5IHVw
seq_yd文件爲base64編碼後的內容,decode後數據爲:
hello zhanghao
hello feifei,good good study,day day up
create table cus(str STRING)
stored as
inputformat 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextInputFormat'
outputformat 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextOutputFormat';
LOAD DATA LOCAL INPATH '/home/hivedata/cus' INTO TABLE cus;
配置文件相關內容
hive-default.xml.template
<property>
<name>hive.default.fileformat</name>
<value>TextFile</value>
<description>
Expects one of [textfile, sequencefile, rcfile, orc].
Default file format for CREATE TABLE statement. Users can explicitly override it by CREATE TABLE ... STORED AS [FORMAT]
</description>
</property>
二、文件壓縮
2.1 map輸出壓縮
mapreduce.map.output.compress=false
mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
2.2 reduce輸出壓縮(reduce壓縮)
snappy、bzip2、gzip、DefaultCompress
mapreduce.output.fileoutputformat.compress=false
mapreduce.output.fileoutputformat.compress.type=NONE/RECORD/BLOCK(默認RECORD)
mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
2.3 壓縮配置
set hive.exec.compress.output=false;
set hive.exec.compress.intermediate=false;
set hive.intermediate.compression.codec=
set hive.intermediate.compression.type=
CREATE TABLE `u4`(
`id` int,
`name` string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
stored as textfile;
set mapreduce.output.fileoutputformat.compress=true;
set hive.exec.compress.output=true;
insert into table u4
select * from u2;
2.4 壓縮算法
snappy、bzip2、gzip、DefaultCompress
2.5 lzo壓縮(未完成)
2.6 snaapy壓縮(未完成)
三、Hive視圖
3.1 視圖簡介
hive的視圖簡單理解爲邏輯上的表
hive現目前只支持邏輯視圖,不支持物化視圖。
hive的視圖意義:
1、對數據進行局部暴露(涉及隱私數據不暴露)。
2、簡化複雜查詢。
3.2 創建視圖
create view if not exists tab_v1
as
select id from u2;
3.3 查看視圖
show tables;
show create table tab_v1;
desc tab_v1;
3.4 刪除視圖
drop view if exists tab_v2;
drop table if exists tab_v1; (drop是刪除表,不能用於刪除視圖)
3.5 注意事項
1、不建議先刪除視圖對應的表後再查詢視圖。
2、視圖是不能用insert into 或者load 方式來加載數據。
3、視圖是隻讀,不能修改其結構、表相關屬性。
四、Hive日誌
4.1 Hive的系統日誌
默認目錄:/tmp/{user.name}
hive.log.dir={java.io.tmpdir}/{user.name}
hive.log.file=hive.log
4.2 Hive的查詢日誌
// hive-default.xml.template
<property>
<name>hive.querylog.location</name>
<value>${system:java.io.tmpdir}/${system:user.name}</value>
<description>Location of Hive run time structured log file</description></property>
五、Hive運行方式
beeline的配置
5.1 Hive的屬性設置
1、hive-site.xml
2、hive通過命令行參數設置
3、hive通過cli端set設置
5.2 三種設置方式的區別
1、屬性設置優先級從上往下依次升高
2、hive-site.xml是全局和永久的,其它兩個是臨時和局部的
3、hive-site.cml適合所有屬性配置,而後兩個對於系統級別的屬性不能配置,比如啓動所需的元數據庫url、log的配置等。
5.3 Hive的四類屬性
hiveconf:可讀可寫
hivevar:自定義臨時變量,可讀可寫
system:可讀可寫
env:可讀不可寫
--hiveconf <property=value> Use value for given property
--hivevar <key=value> Variable subsitution to apply to hive
commands. e.g. --hivevar A=B
hive -e
hive -f
hive -S 靜音模式
hive -i
hive --database
hive>set -v; ##查看hive相關的環境變量
hive -e "set" | grep current ##單個查找
5.4 Hive的三種運行方式
在hive的cli端運行:(開發測試,以及臨時跑作業)
通過命令行 hive -e 'sql query';
通過命令行 hive -f /hql文件 (生產線)
hive --database qf1701 -e 'select * from text1';
hive --database qf1701 --hivevar ls=2 --hiveconf tn=text1 -e 'select * from ${hiveconf:tn} limit ${hivevar:ls}';
hive -S --hivevar mapoutputdir=/home/hivedata/out/05 --hivevar textoutdir=/home/hivedata/out/06 --hivevar limit=1 -f ./hql
注意:
1、一個--hivevar 或者 --hiveconf 只能帶一個參數
2、--hiveconf 或者 --hivevar 可以混合使用
3、--hiveconf 或 --hivevar 定義參數不能取消
六、Hive的遠程模式使用
hive也可以啓動爲一個服務器,來對外提供
啓動方式,(假如是在hadoop01上):
啓動爲前臺:bin/hiveserver2
啓動爲後臺:nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err &
啓動成功後,可以在別的節點上用beeline去連接
方式(1)
hive/bin/beeline 回車,進入beeline的命令界面
輸入命令連接hiveserver2
beeline> !connect jdbc:hive2://hdp01:10000
(hdp01是hiveserver2所啓動的那臺主機名,端口默認是10000)
方式(2)
或者啓動就連接:
bin/beeline -u jdbc:hive2://hdp01:10000 -n hadoop
接下來就可以做正常sql查詢了
七、Hive的JDBC
7.1 實例
pom.xml
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>1.2.1</version>
</dependency>
HiveJdbc.java
package HiveJdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import util.HiveJdbcUtil;
/**
* hive的連接
*/
public class HiveJDBC {
private static Connection conn = null;
public static void main(String[] args) {
selectDemo();
}
//查詢某天某公司的員工數量
public static void selectDemo(){
conn = HiveJdbcUtil.getConn();
PreparedStatement ps = null;
ResultSet rs = null;
try {
//獲取ps
ps = conn.prepareStatement("select \n" +
"*\n" +
"from t1 \n");
//爲佔位符賦值
// ps.setInt(1,1);
//執行查詢
rs = ps.executeQuery();
//遍歷結果集
while (rs.next()){
System.out.println(rs.getString(1) + "\t"
+ rs.getString(2) + "\t" + rs.getString(3));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
HiveJdbcUtil.closeConn(conn,ps,rs);
}
}
}
HiveJdbcUtil.java
package util;
import java.sql.*;
/**
* 連接工具類
*/
public class HiveJdbcUtil {
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
private static String url = "jdbc:hive2://hadoop01:10000/leo"; //指定數據庫爲dw_hivedata
private static String userName = "root"; //hiveserver2的用戶名和密碼
private static String password = "123456";
public static void main(String[] args) {
System.out.println(getConn());
}
/**
*獲取hive的驅動連接
* @return
*/
public static Connection getConn(){
Connection conn = null;
try {
Class.forName(driverName); //加載驅動
//獲取conn
conn = DriverManager.getConnection(url, userName, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
} catch (SQLException e){
e.printStackTrace();
}
return conn;
}
/**
* 關閉連接
* @param conn
*/
public static void closeConn(Connection conn, PreparedStatement ps , ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps != null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
7.2 注意
1、conn、ps\rs的關閉順序需要時rs\ps\conn,否則報錯sasl
2、連接的用戶名和密碼需要 填寫,如果沒有配置可以使用root、root,否則會報錯沒有權限。
7.3 優化
kylin:加速hive的查詢(將查詢預執行,並將結果保存在Hbase中)
八、Hive的優化
1、考慮環境(硬件服務器、配置)
2、業務 (統計指標的實現思路)
3、代碼或者配置屬性
8.1、explain 和 explain extended
explain select * from text1;
explain extended select * from text1;
explain extended
select
d.deptno as deptno,
d.dname as dname
from dept d
union all
select
d.dname as dname,
d.deptno as deptno
from dept d
;
explain : 只有對hql語句的解釋。
explain extended:對hql語句的解釋,以及抽象表達式樹的生成。
stage 相當於一個job,一個stage可以是limit、也可以是一個子查詢、也可以是group by等。
hive默認一次只執行一個stage,但是如果stage之間沒有相互依賴,將可以並行執行。
任務越複雜,hql代碼越複雜,stage越多,運行的時間一般越長。
8.2、join
hive的查詢永遠是小表(結果集)驅動大表(結果集)
hive中的on的條件只能是等值連接
注意hive是否配置普通join轉換成map端join、以及mapjoin小表文件大小的閥值
注意hive的傾斜join:
8.3、limit的優化
hive.limit.row.max.size=100000
hive.limit.optimize.limit.file=10
hive.limit.optimize.enable=false (如果limit較多時建議開啓)
hive.limit.optimize.fetch.max=50000
8.4、本地模式
hive.exec.mode.local.auto=false (建議打開)
hive.exec.mode.local.auto.inputbytes.max=134217728(128M)
hive.exec.mode.local.auto.input.files.max=4
8.5、並行執行
hive.exec.parallel=false (建議開啓)
hive.exec.parallel.thread.number=8
8.6、嚴格模式
hive.mapred.mode=nonstrict
Cartesian Product.
No partition being picked up for a query.
Orderby without limit.
Comparing bigints and strings.
Comparing bigints and doubles.
select
e.*
from dept d
join emp e
;
select
e.*
from emp e
order by e.empno desc
;
create table text9 (
uid bigint,
uid1 double
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
;
LOAD DATA LOCAL INPATH '/home/hivedata/text8' INTO TABLE text9;
select
- from text9 t
where t.uid = t.uid1
;
8.7、mapper和reducer的個數
不是mapper和redcuer個數越多越好,也不是越少越好,適合即可。
將小文件合併處理(將輸入類設置爲:CombineTextInputFormat)
通過配置將小文件合併:
mapred.max.split.size=256000000
mapred.min.split.size.per.node=1
mapred.min.split.size.per.rack=1
hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
手動設置:
set mapred.map.tasks=2;
reducer的個數(自動決定和手動設置):
mapred.reduce.tasks=-1
hive.exec.reducers.max=1009
8.8、配置jvm重用
mapreduce.job.jvm.numtasks=1 ###
mapred.job.reuse.jvm.num.tasks=1
8.9、數據傾斜
由於key分佈不均勻造成的數據向一個方向偏離的現象
join語句、count(distinct col)、group by都認識容易造成數據傾斜的
傾斜現象:
卡在某一個reduce任務
解決方法:
1、找到造成數據傾斜的key,然後再通過hql語句避免(查看日誌是那個task失敗-->找到該task關聯字段、group by\count(distrinct col)-->抽樣字段個數-->判斷是否是傾斜的key)。單獨拿出來處理,然後再和正常的結果進行union all
2、造成傾斜的key加隨機數(加的隨機不能造成二次傾斜、保證加隨機不能影響原有的業務)
3、設置相關傾斜的屬性
hive.map.aggr=true;
hive.groupby.skewwindata=false;(建議開啓)
hive.optimize.skewjoin=false;
4、如上都不行,則需要重新查看業務,優化語句流程
8.10、索引
索引是一種hive的優化
8.11、分區
分區本身就是hive的一種優化
8.12、job的數量
一般是一個查詢產生一個job,然後通常情況一個job、可以是一個子查詢、一個join、一個group by 、一個limit等一些操作。
1個job:
select
a.*
from t1 a
left join t1 b
on a.order_id = b.order_id
;
8.13 analyze
參考官網:https://cwiki.apache.org/confluence/display/Hive/StatsDev
Analyze,分析表(也稱爲計算統計信息)是一種內置的Hive操作,可以執行該操作來收集表上的元數據信息。這可以極大的改善表上的查詢時間,因爲它收集構成表中數據的行計數,文件計數和文件大小(字節),並在執行之前將其提供給查詢計劃程序。
已經存在表的Analyze語法:
ANALYZE TABLE [db_name.]tablename [PARTITION(partcol1[=val1], partcol2[=val2], ...)] -- (Note: Fully support qualified table name since Hive 1.2.0, see HIVE-10007.)
COMPUTE STATISTICS
[FOR COLUMNS] -- (Note: Hive 0.10.0 and later.)
[CACHE METADATA] -- (Note: Hive 2.1.0 and later.)
[NOSCAN];
例1(指定分區)、
ANALYZE table dw_employee_hive partition(bdp_day=20190701) COMPUTE STATISTICS;
收集表的bdp_day=20190701的這個分區下的所有列列相關信息。它是一個細粒度的分析語句。它收集指定的分區上的元數據,並將該信息存儲在Hive Metastore中已進行查詢優化。該信息包括每列,不同值的數量,NULL值的數量,列的平均大小,平均值或列中所有值的總和(如果類型爲數字)和值的百分數。
例2(指定所有列)、
ANALYZE table dw_employee_hive partition(bdp_day=20190701) COMPUTE STATISTICS FOR COLUMNS;
收集表的bdp_day=20190701的這個分區下的所有列相關信息。
例3(指定某列)、
ANALYZE table dw_employee_hive partition(bdp_day=20190701) COMPUTE STATISTICS FOR COLUMNS snum,dept;
例4、
ANALYZE TABLE dw_employee_hive partition(bdp_day=20190701) COMPUTE STATISTICS NOSCAN;
收集指定分區相關信息,然後不進行掃描。
測試分析後的結果。
例1、
DESCRIBE EXTENDED dw_employee_hive partition(bdp_day=20190701);
描述結果:
...parameters:{totalSize=10202043, numRows=33102, rawDataSize=430326, ...
例2、
desc formatted dw_employee_hive partition(bdp_day=20190701) name;
結果如下:
# col_name data_type min max num_nulls distinct_count avg_col_len max_col_len num_trues num_falses comment
name string 0 37199 4.0 4 from deserializer
注意:
對分區表的分析,一般都要指定分區,如對全表分析,則可以這樣使用partition(bdp_day).
優化後查詢結果可以參考:https://www.cnblogs.com/lunatic-cto/p/10988342.html