目錄
· 概況
· 手工安裝
· 引言
· 創建HDFS目錄
· 創建元數據庫
· 配置文件
· 測試
· 原理
· 架構
· API
· 命令
· 數據類型
· 文件存儲格式
· 數據格式
· 數據庫
· 數據表
· 裝載數據
· 插入數據
· 導出數據
· 查詢數據
· 函數
· 性能調優
· join調優
· 合並小文件
· multi-group-by insert和multiple insert
· 並行執行
· Top N調優
概況
1. 設計目標:讓精通SQL而Java技能較弱的數據分析師能利用Hadoop數據分析。
2. 使用率:實際開發中,80%操作使用Hive完成,20%使用MapReduce。
3. 與MapReduce相比,Hive特點:穩定、代碼精簡、易於維護。
4. HiveQL:未嚴格實現SQL-92標准。
5. 本質:將HiveQL轉化為一個或多個MapReduce作業並在集群上運行,但並不是所有HiveQL都會轉為MapReduce作業。
手工安裝
引言
1. 假設已成功安裝JDK、Hadoop集群及MySQL。
2. 本次手工安裝在Hadoop的Master節點上。
3. 創建HDFS目錄並分配權限。
創建HDFS目錄
hadoop fs -mkdir /tmp hadoop fs -mkdir /user/hive/warehouse hadoop fs -chmod g+w /tmp hadoop fs -chmod g+w /user/hive/warehouse
創建元數據庫
2. 創建MySQL元數據庫。
create database hive character set latin1;
3. 創建用戶。
grant all on hive.* to 'hive'@'localhost' identified by 'hive'; grant all on hive.* to 'hive'@'%' identified by 'hive'; flush privileges;
配置文件
4. 創建MySQL元數據庫。
tar zxvf apache-hive-1.2.2-bin.tar.gz -C /opt/app cp mysql-connector-java-5.1.42.jar /opt/app/apache-hive-1.2.2-bin/lib cd /opt/app/apache-hive-1.2.2-bin vi conf/hive-site.xml
<configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value><![CDATA[jdbc:mysql://centos1:3306/hive?characterEncoding=latin1]]></value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hive</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>hive</value> </property> </configuration>
測試
5. 配置環境變量。
vi /home/hadoop/.bash_profile
export HIVE_HOME=/opt/app/apache-hive-1.2.2-bin export PATH=$PATH:$HIVE_HOME/bin export HADOOP_USER_CLASSPATH_FIRST=true
source /home/hadoop/.bash_profile env | grep HIVE_HOME
6. 啟動與測試。
hive
hive> show tables;
原理
架構
1. 訪問接口:CLI(命令行)、HWI(Hive網絡界面)、Thrift Server提供的JDBC和ODBC。
2. Driver職責:通過訪問接口提交的命令,由Driver模塊解釋和編譯,對計算優化,生成執行計划執行,執行計划由若干MapReduce作業組成。
3. Metastore:Hive元數據存儲,通常是關系型數據庫(例如MySQL、PostgreSQL、Oracle)。
4. 部署:Hive通過與YARN通信來執行MapReduce作業,所以Hive無需部署在YARN集群。
與關系型數據庫對比
|
Hive |
RDBMS |
查詢語言 |
HiveQL |
SQL |
數據存儲位置 |
HDFS |
Raw Device或本地文件系統 |
數據格式 |
用戶定義 |
系統決定 |
數據更新 |
不支持 |
支持 |
索引 |
無 |
有 |
執行 |
MapReduce |
Executor |
執行延遲 |
高 |
低 |
伸縮性 |
高 |
低 |
數據規模 |
大 |
小 |
事務 |
無 |
一般有 |
API
WordCount
create table wordcount_in ( line string ); load data local inpath '/opt/app/apache-hive-1.2.2-bin/LICENSE' overwrite into table wordcount_in; create table wordcount_out as select word, count(1) as count from ( select explode(split(line, ' ')) as word from wordcount_in ) words group by word order by word; select * from wordcount_out;
命令
1. hive命令
a) 官方文檔
b) 示例
hive -e 'select * from wordcount_out' hive -f hive-script.sql
2. beeline命令
a) 官方文檔
數據類型
1. 基本數據類型
數據類型 |
長度 |
示例 |
tinyint |
1字節,有符號整數 |
11 |
smallint |
2字節,有符號整數 |
11 |
int |
4字節,有符號整數 |
11 |
bigint |
8字節,有符號整數 |
11 |
float |
4字節,單精度浮點數 |
11.0 |
double |
8字節,雙精度浮點數 |
11.0 |
boolean |
布爾值 |
TRUE |
string |
字符串 |
'hadoop' |
2. 復雜數據類型
數據類型 |
長度 |
示例 |
struct |
結構體,可通過“列名.屬性名”訪問,如struct(first_name string, last_name string) |
struct('Harry', 'Potter') |
map |
鍵值對集合,可通過“列名.鍵”訪問 |
map('first_name', 'Harry', 'last_name', 'Potter') |
array |
數組,即相同數據類型的變量集合,可通過“列名[索引]”訪問(索引從0開始) |
array('Harry', 'Potter') |
3. 更多數據類型參考官方文檔。
文件存儲格式
1. textfile
a) 原理:平面文本文件,默認格式。
b) 特點:未壓縮,磁盤開銷大,數據解析開銷大。
2. sequencefile
a) 原理:二進制格式。
b) 特點:使用方便、可分割、可壓縮,數據按行切分。
3. rcfile
a) 原理:行列存儲結合的存儲方式。
b) 特點:數據按行分塊,保證同一行數據在一個塊上,避免讀取一行需要讀取多個塊。
4. parquet
a) 原理:面向分析性業務的列式存儲格式。
b) 特點:對Impala有顯著性能提升。
數據格式
1. 默認使用少用字符作為分隔符
分隔符 |
描述 |
\n |
換行符,默認行分隔符 |
^A(Ctrl+A) |
在文本中以八進制編碼\001表示,列分隔符 |
^B(Ctrl+B) |
在文本中以八進制編碼\002表示,array、struct元素分隔符 |
^C(Ctrl+C) |
在文本中以八進制編碼\003表示,map鍵值對分隔符 |
2. 自定義(此處仍然使用默認分隔符)
create table test_table ( test_string string, test_int int, test_array array<string>, test_struct struct<test_struct_string:string, test_struct_int:int>, test_map map<string, int> ) row format delimited fields terminated by '\001' collection items terminated by '\002' map keys terminated by '\003' lines terminated by '\n' stored as textfile;
數據庫
1. 本質:表的目錄或命名空間。
2. 場景:生產環境如果表較多,則一般使用數據庫將表邏輯分組。
3. 默認數據庫:default。
4. 存儲結構
a) 庫:一個HDFS目錄,如test_database其他為/user/hive/warehouse/test_database.db。
b) 表:數據庫HDFS目錄的子目錄。
c) default庫:HDFS目錄/user/hive/warehouse。
5. 查看
show databases; describe database test_database;
6. 創建
create database test_database; create database test_database location '/test/hive/test_database';
7. 切換
use test_database;
8. 刪除
drop database test_database; drop database if exists test_database; -- 避免不存在引起的錯誤 drop database test_database cascade; -- 其中的表一起刪除(默認不允許刪除非空數據庫)
數據表
1. 管理表:managed table,數據完全由Hive管理。
2. 外部表:external table,數據除Hive管理外,還會有其他分析工具管理,如Pig。
3. 管理表與外部表區別
a) 刪除:刪除管理表會刪除元數據及其數據;刪除外部表僅刪除元數據。
b) 注意:創建表時是否指定location,管理表、外部表並無區別。
4. 分區表
a) 含義:將表水平切分,數據按某種規則存儲。
b) 分區字段報錯:分區字段不能與表定義字段同名,否則報錯“Column repeated in partitioning columns”。
c) 存儲目錄
/user/hive/warehouse/test_order/year=1999/month=11 /user/hive/warehouse/test_order/year=1999/month=12 /user/hive/warehouse/test_order/year=2000/month=01 /user/hive/warehouse/test_order/year=2000/month=02 /user/hive/warehouse/test_order/year=2000/month=03
d) 查詢性能:查詢大數據集時,根據分區字段查詢,僅掃描分區目錄下的數據,性能比非分區表的全表掃描有顯著提升。
select * from test_order where year = '2000' and month = '01';
e) 常用分區字段:生產環境常按創建時間或修改時間分區。
f) strict模式:如果針對分區表的查詢未對分區限制,則禁止提交;修改hive-site.xml參數“hive.mapred.mode”為strict。
5. 查看
a) 表
show tables; show tables in test_database; -- 指定數據庫 desc test_table; -- 表結構 desc extended test_table; -- 表級別信息 desc formatted test_table; -- 表級別信息
b) 分區
show partitions test_order;
6. 創建
a) 管理表
create table if not exists test_table ( test_string string, test_int int ) location '/test/hive/test_table'; create table test_table_bak1 like test_table; -- 復制表結構,不復制數據 create table test_table_bak2 as select test_string from test_table;
b) 外部表
create external table test_table ( test_string string, test_int int );
c) 分區表
create table test_order ( order_no string, balance double ) partitioned by (year string, month string);
7. 刪除
drop table test_table; drop table if exists test_table;
8. 修改
a) 重命名
alter table test_table rename to test_table_new;
b) 增加分區
alter table test_order add partition (year='2000', month='04'); alter table test_order add partition (year='2000', month='05') location '/test/hive/test_order/year=2000/month=05';
c) 修改分區路徑
alter table test_order add partition (year='2000', month='05') set location '/test_order/year=2000/month=05';
d) 刪除分區
alter table test_order drop partition (year='2000', month='04');
e) 修改列
alter table test_table change column test_int test_double double comment 'new column' after test_string;
f) 增加列
alter table test_table add columns ( test_long long, test_float float );
g) 重定義列
alter table test_table replace columns (col1 string, col2 string, col3 string);
裝載數據
1. 以追加方式將HDFS文件移動到表
load data inpath '/test/data' into table test_table;
2. 以覆蓋方式將HDFS文件移動到表
load data inpath '/test/data' overwrite into table test_table;
3. 以追加方式將本地文件復制到表
load data local inpath '/opt/test/data' into table test_table;
4. 以覆蓋方式將本地文件復制到表
load data local inpath '/opt/test/data' overwrite into table test_table;
插入數據
1. 以覆蓋方式插入非分區表
insert overwrite table test_table select * from test_source;
2. 以覆蓋方式插入分區表
insert overwrite table test_order partition (year='2000', month='05') select * from test_source;
3. 以追加方式插入非分區表
insert into table test_table select * from test_source;
4. 以追加方式插入分區表
insert into table test_order partition (year='2000', month='05') select * from test_source;
5. multiple insert
from test_source insert into table test_order partition (year='2000', month='05') select order_no, balance where order_no >= '0001' and order_no < '1000' insert into table test_order partition (year='2000', month='06') select order_no, balance where order_no >= '1000' and order_no < '5000' insert overwrite table test_order partition (year='2000', month='07') select order_no, balance where order_no >= '5000' and order_no < '9000';
6. 動態分區插入
a) 含義:Hive根據查詢結果最后幾個字段作為分區字段自動創建分區並插入數據,這些字段需與分區字段順序一致。
b) 參數
Configuration Property |
Default |
Note |
hive.exec.dynamic.partition |
true |
Whether or not to allow dynamic partitions in DML/DDL. |
hive.exec.dynamic.partition.mode |
strict |
In strict mode, the user must specify at least one static partition in case the user accidentally overwrites all partitions. In nonstrict mode all partitions are allowed to be dynamic. |
hive.exec.max.dynamic.partitions.pernode |
100 |
Maximum number of dynamic partitions allowed to be created in each mapper/reducer node. |
hive.exec.max.dynamic.partitions |
1000 |
Maximum number of dynamic partitions allowed to be created in total. |
hive.exec.max.created.files |
100000 |
Maximum number of HDFS files created by all mappers/reducers in a MapReduce job. |
hive.error.on.empty.partition |
false |
Whether to throw an exception if dynamic partition insert generates empty results. |
c) 示例
from page_view_stg pvs insert overwrite table page_view partition(dt='2008-06-08', country) select pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip, pvs.cnt;
導出數據
1. 導出到HDFS
insert overwrite directory '/test/hive/data' select * from test_table;
2. 導出到本地磁盤
insert overwrite local directory '/opt/test/data' select * from test_table;
查詢數據
1. select...from...
select test_string, test_int from test_table;
a) 表別名
select t.test_string, t.test_int from test_table t;
b) 嵌套查詢
select s.name, sc.course from (select id, name from student_info) s join (select id, course from student_class_info) sc on s.id = sc.id;
c) 限制返回行數
select * from test_table limit 100;
d) case...when...then...
select id, name, case when gender = 'm' then '男' when gender = 'f' then '女' else '保密' end from student_info;
2. where
select * from student_info where gender = 'm';
3. group by與having
select gender, count(id) from student_info group by gender;
4. inner join
select s.id, s.name from student_info s inner join student_class_info sc on s.id = sc.id; select * from t1 join t2 on t1.id = t2.id join t3 on t1.id = t3.id;
5. left outer join
select s.id, s.name from student_info s left outer join student_class_info sc on s.id = sc.id;
6. right outer join
select s.id, s.name from student_info s right outer join student_class_info sc on s.id = sc.id;
7. full outer join
select s.id, s.name from student_info s full outer join student_class_info sc on s.id = sc.id;
8. left-semi join
a) left-semi join效果:如果左表數據對於右表滿足on條件,則返回左表數據。
b) left-semi join場景:替代標准SQL的in操作。Hive不支持如下in操作:
select s.id, s.name from student_info s where s.id in (select sc.id from student_class_info sc);
c) left-semi join原理:當左表的一條數據一旦滿足右表的on條件,則停止掃描該左表數據對應的右表,所以left-semi join效率高於inner join。
d) 示例:效果相同,但前者效率高於后者。
select s.id, s.name from student_info s left semi join student_class_info sc on s.id = sc.id; select s.id, s.name from student_info s inner join student_class_info sc on s.id = sc.id;
9. map-side join
a) map-side join原理:如果有一張小表,則將該小表加載到內存,直接在map階段進行join,效率大大提升。
b) 非map-side join原理:通過在reduce階段求笛卡爾積進行join,效率相對較低。
c) 示例
select /*+ mapjoin(s) */ s.name, sc.course from student_info s join student_class_info sc on s.id = sc.id;
10. order by與sort by
a) order by:全局有序。
b) sort by:每個Reduer局部有序。
c) 示例
select * from student_info order by id asc, name desc; select * from student_info sort by id asc, name desc;
11. distribute by與cluster by
a) distribute by:相當於MapReduce的Partitioner,即控制中間結果分發的目的Reducer。
b) cluster by:如果distribute by和sort by的列相同且正序,可用cluster by替代。
c) 示例
select * from student_info distribute by id sort by id asc, name desc;
12. 抽樣
a) 公式: “bucket x out of y on z”,根據z列的哈希值將數據分為y桶,取其中第x桶。
b) 分桶抽樣
select * from student_info tablesample(bucket 3 out of 10 on id);
c) 隨機抽樣
select * from student_info tablesample(bucket 3 out of 10 on rand());
13. union all
a) 注意:Hive不支持直接union all,須嵌套查詢。
b) 示例
select s.id, s.name from ( select s1.id, s1.name from student_info s1 union all select s2.id, s2.name from student_info s2 ) s;
函數
1. 標准函數
a) 含義:操作一行數據,產生一個值。
b) 內置函數參考官方文檔。
2. 聚合函數
a) 含義:操作多行數據,產生一個值。
b) 內置函數參考官方文檔。
3. 表生成函數
a) 含義:操作一行數據,產生多行數據。
b) 內置函數參考官方文檔。
4. 自定義函數開發
a) Maven依賴
<dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.6.5</version> </dependency>
b) 使用方法:注冊jar文件“add jar /opt/test/test-hive.jar;”;創建函數“create temporary function concat_udf as 'hive.ConcatUDF';”;查看“show functions”。
5. 自定義標准函數(UDF)
a) 方法:繼承UDF,並實現evaluate()方法(不是Override,因為無法預知參數)。
b) 示例
1 package hive; 2 3 import org.apache.hadoop.hive.ql.exec.UDF; 4 import org.apache.hadoop.io.Text; 5 6 public class ConcatUDF extends UDF { 7 8 private Text result = new Text(); 9 10 public Text evaluate(Text str1, Text str2) { 11 if (str1 == null || str2 == null) { 12 return null; 13 } 14 result.set(str1.toString() + str2.toString()); 15 return result; 16 } 17 18 }
6. 自定義聚合函數(UDAF)。
7. 自定義表生成函數(UDTF)。
性能調優
join調優
1. 大表置右:大表放在join右邊,性能更好。
2. map-side join:如果小表可加載到內存,則考慮map-side join。
Reduce任務數
1. 原理:與mapred-site.xml的mapreduce.job.reduces參數原理相同,設置為0.95×NodeManager節點數或1.75×NodeManager節點數。
2. 調優:reduce任務數 = min(hive.exec.reducers.max參數值, 總輸入數據量 ÷ hive.exec.reducers.bytes.per.reducer參數值)。
a) hive.exec.reducers.bytes.per.reducer
i. 默認值:256000000
ii. 官方描述:size per reducer.The default is 256Mb, i.e if the input size is 1G, it will use 4 reducers.
b) hive.exec.reducers.max
i. 默認值:1009
ii. 官方描述:max number of reducers will be used. If the one specified in the configuration parameter mapred.reduce.tasks is negative, Hive will use this one as the max number of reducers when automatically determine number of reducers.
合並小文件
1. 原理:文件數目過多給HDFS帶來壓力,通過合並map和reduce階段輸出文件減少文件數。
2. 調優
a) hive.merge.mapfiles:合並map階段輸出文件,默認true。
b) hive.merge.mapredfiles:合並reduce階段輸出文件,默認false。
c) hive.merge.size.per.task:合並后文件大小,默認256000000。
multi-group-by insert和multiple insert
1. 原理:multi-group-by insert和multiple insert在同一條語句使用多個不相交的insert語句,只需一次全表掃描,效率高於多個insert。
2. multi-group-by insert示例
from test_source insert into table test_target select a, count(e) group by a insert into table test_target select b, count(f) group by b insert overwrite table test_target select c, count(g) group by c;
3. multiple insert示例:見插入數據。
union all合並MapReduce
1. union all可合並執行多個MapReduce作業。
2. 調優前:執行3個MapReduce。
select * from ( select * from t1 group by c1, c2, c3 union all select * from t2 group by c1, c2, c3 ) t group by c1, c2, c3;
3. 調優后:執行1各MapReduce。
select * from ( select * from t1 union all select * from t2 ) t group by c1, c2, c3;
並行執行
1. 原理:一個HiveQL被拆分為多個MapReduce作業,如果作業之間相互獨立、無依賴,則可並行執行。
2. 調優:設置hive.exec.parallel為true(默認false),即開啟並行執行。
Top N調優
1. 原理
a) 調優前:如果使用order by...limit n,則執行1個作業,所有數據集中到一個reduce任務排序。
b) 調優后:如果使用sort by...limit n,則執行2個作業,第1個作業M個reduce任務局部排序,分別求Top N,第2個作業reduce任務接收M×N條數據排序求Top N。
作者:netoxi
出處:http://www.cnblogs.com/netoxi
本文版權歸作者和博客園共有,歡迎轉載,未經同意須保留此段聲明,且在文章頁面明顯位置給出原文連接。歡迎指正與交流。