1、知識梳理1.一、背景表結構1.1.一、order by1.1.二、sort by1.1.三、distribute by1.1.四、cluster by1.二、行轉列、列轉行(UDAF 與 UDTF)1.2.一、行轉列1.2.二、列轉行1.三、建表時的數組操做1.四、orc 存儲1.五、Hive 分桶1.5.一、直接分桶1.5.二、在分區中分桶2、總結2.1 啓動/中止hadoop集羣、zookeeper集羣、歷史服務器2.2 訪問hive的兩種方式2.3 CentOS6x與Cenos7x命令的區別2.4 大數據開發中重用的兩種數據格式2.5 UDF、UDAF、UDTF2.6 小知識總結html
在講解中咱們須要貫串一個例子,因此須要設計一個情景,對應還要有一個表結構和填充數據。以下:有 3 個字段,分別爲 personId 標識某一我的,company 標識一家公司名稱,money 標識該公司每一年盈利收入(單位:萬元人民幣)mysql
create table company_info(
personId string,
company string,
money float
)
row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/company_info.txt' into table company_info;
hive 中的 order by 語句會對查詢結果作一次全局排序
,即,全部的 mapper 產生的結果都會交給一個 reducer 去處理,不管數據量大小,job 任務只會啓動一個 reducer,若是數據量巨大,則會耗費大量的時間。
尖叫提示
:若是在嚴格模式下,order by 須要指定 limit 數據條數,否則數據量巨大的狀況下會形成崩潰無輸出結果。涉及屬性:set hive.mapred.mode=nonstrict/strict
例如:按照 money 排序的例子算法
select * from company_info order by money desc;
hive 中的 sort by 語句會對每一塊局部數據進行局部排序
,即每個 reducer 處理的數據都是有序的,可是不能保證全局有序。sql
hive 中的 distribute by 通常要和 sort by 一塊兒使用,即將某一塊數據歸給(distribute by)某一個 reducer 處理,而後在指定的 reducer 中進行 sort by 排序。
尖叫提示
:distribute by 必須寫在 sort by 以前。
尖叫提示
:涉及屬性 mapreduce.job.reduces,hive.exec.reducers.bytes.per.reducer
例如:不一樣的人(personId)分爲不一樣的組,每組按照 money 排序。express
select * from company_info distribute by personId sort by personId asc, money desc;
hive 中的 cluster by 在 distribute by 和 sort by 排序字段一致
的狀況下是等價的。同時,cluster by 指定的列只能是降序
,即默認的 descend,而不能是 ascend。
例如:寫一個等價於 distribute by 與 sort by 的例子。vim
select * from company_info distribute by personId sort by personId desc;
等價於
select * from compnay_info cluster by personId;
一、相關函數說明
1)CONCAT(string A/col, string B/col, …):返回輸入字符串鏈接後的結果,支持任意個輸入字符串。
2)CONCAT_WS(separator, str1, str2,…):它是一個特殊形式的CONCAT()
。第一個參數是剩餘參數間的分隔符。分隔符能夠是與剩餘參數同樣的字符串。若是分隔符是 NULL,返回值也將爲 NULL。這個函數會跳過度隔符參數後的任何 NULL 和空字符串。分隔符將被加到被鏈接的字符串之間。
3)COLLECT_SET(col):函數只接受基本數據類型,它的主要做用是將某字段的值進行去重彙總,產生array類型字段
。
二、數據準備
person_info.txt數組
射手座,A 大海|鳳姐
白羊座,A 孫悟空|豬八戒
白羊座,B 宋宋
分析過程:ruby
[atguigu@hadoop102 datas]$ vim person_info.txt
孫悟空 白羊座 A
大海 射手座 A
宋宋 白羊座 B
豬八戒 白羊座 A
鳳姐 射手座 A
五、建立hive表並導入數據服務器
create table person_info(
name string,
constellation string,
blood_type string
)
row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/person_info.txt' into table person_info;
六、按需求查詢數據app
select concat_ws(",", constellation, blood_type) as c_b, name from person_info; t1
+--------+-------+--+
| c_b | name |
+--------+-------+--+
| 白羊座,A | 孫悟空 |
| 射手座,A | 大海 |
| 白羊座,B | 宋宋 |
| 白羊座,A | 豬八戒 |
| 射手座,A | 鳳姐 |
+--------+-------+--+
--------------------
select
t1.c_b, collect_set(t1.name)
from
(select concat_ws(",", constellation, blood_type) as c_b, name from person_info) t1
group by
t1.c_b;
+---------+----------------+--+
| t1.c_b | _c1 |
+---------+----------------+--+
| 射手座,A | ["大海","鳳姐"] |
| 白羊座,A | ["孫悟空","豬八戒"] |
| 白羊座,B | ["宋宋"] |
+---------+----------------+--+
--------------------
select
t1.c_b, concat_ws("|", collect_set(t1.name)) name
from
(select concat_ws(",", constellation, blood_type) as c_b, name from person_info) t1
group by
t1.c_b;
+---------+----------+--+
| t1.c_b | name |
+---------+----------+--+
| 射手座,A | 大海|鳳姐 |
| 白羊座,A | 孫悟空|豬八戒 |
| 白羊座,B | 宋宋 |
+---------+----------+--+
一、函數說明
EXPLODE(col):將hive一列中複雜的array或者map結構拆分紅多行。
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解釋:lateral view 用於和split,explode等UDTF函數一塊兒使用,它可以將一列數據拆成多行數據,在此基礎上能夠對拆分後的數據進行聚合。
二、數據準備
movie_info.txt
movie category
《疑犯追蹤》 懸疑,動做,科幻,劇情
《Lie to me》 懸疑,警匪,動做,心理,劇情
《戰狼2》 戰爭,動做,災難
三、需求
將電影分類中的數組數據展開。結果以下:
《疑犯追蹤》 懸疑
《疑犯追蹤》 動做
《疑犯追蹤》 科幻
《疑犯追蹤》 劇情
《Lie to me》 懸疑
《Lie to me》 警匪
《Lie to me》 動做
《Lie to me》 心理
《Lie to me》 劇情
《戰狼2》 戰爭
《戰狼2》 動做
《戰狼2》 災難
四、建立本地movie.txt,導入數據
[atguigu@hadoop102 datas]$ vim movie_info.txt
《疑犯追蹤》 懸疑,動做,科幻,劇情
《Lie to me》 懸疑,警匪,動做,心理,劇情
《戰狼2》 戰爭,動做,災難
五、建立hive表並導入數據
create table movie_info(
movie string,
category array<string>
)
row format delimited fields terminated by "\t" -- 表中字段與字段之間的分割符是\t
collection items terminated by ","; -- 集合字段中的每一個元素之間的分隔符是逗號
load data local inpath "/opt/module/datas/movie_info.txt" into table movie_info;
六、按需求查詢數據
select
movie
explode(category)
from
movie_info;
上面是錯誤的。假設能執行的話,獲得的是笛卡爾積。
小結:像split,explode等UDTF函數,是不能跟原表的字段直接進行查詢的,UDTF函數必定要和lateral view聯合在一塊用。
-----------------------------------------
select
movie,
category_name
from
movie_info lateral view explode(category) table_tmp as category_name; -- lateral view 對原始表的集合字段進行了側寫,獲得側寫表和側寫列(側寫字段)。
fields terminated by:標識一張表中字段與字段之間的分隔符。
collection items terminated by:標識一個字段(數組字段)中各個子元素(item)的分隔符。注意:如有兩個或兩個以上的數組字段,那麼他們的分隔符都得同樣。
orc 即 Optimized Row Columnar (ORC) file,在 RCFile 的基礎上演化而來,能夠提供一種高效的方法在 Hive 中存儲數據,提高了讀、寫、處理數據的效率。
爲何要用Hive 分桶?
答:分區會產生新的文件和目錄,在HDFS系統上NameNOde的壓力會增大。
Hive 能夠將表或者表的分區進一步組織成桶,以達到:
一、數據取樣效率更高
二、數據處理效率更高
桶經過對指定列進行哈希來實現,將一個列名下的數據切分爲「一組桶」,每一個桶都對應了一個該列名下的一個存儲文件。
開始操做以前,須要將 hive.enforce.bucketing 屬性設置爲 true,以標識 Hive 能夠識別桶。
create table music(
id int,
name string,
size float
)
row format delimited fields terminated by "\t"
clustered by (id) into 4 buckets;
該代碼的意思是將 music 表按照 id 將數據分紅了 4 個桶,插入數據時,會對應 4 個 reduce 操做,輸出 4 個文件。分桶算法
:id.hashCode % 4(桶數)Map集合key去重的原理和set集合去重原理
:先比較哈希值(本質是比較地址值,hashCode()),再比較所對應的具體值(equals())。
set集合存儲數據的本質是使用Map集合
來存儲的。
Map集合存儲數據的本質是使用數組
來存儲的。
數組存儲數據的本質是使用索引+值
來存儲的。
當數據量過大,須要龐大分區數量時,能夠考慮桶,由於分區數量太大的狀況可能會致使文件系統(HDFS)掛掉
,並且桶比分區有更高的查詢效率。數據最終落在哪個桶裏,取決於 clustered by 的那個列的值的 hash 數與桶的個數求餘來決定。雖然有必定離散性,但不能保證每一個桶中的數據量是同樣的。
create table music2(
id int,
name string,
size float
)
partitioned by(date string)
clustered by(id) sorted by(size) into 4 bucket
row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/music2.txt' into table music2 partition(date='2017-08-30');
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh -- 啓動dfs集羣
[atguigu@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh -- 啓動yarn集羣
[atguigu@hadoop102 ~]$ zkstart.sh -- 啓動zookeeper集羣
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/mr-jobhistory-daemon.sh start historyserver -- 啓動歷史服務器
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/stop-dfs.sh -- 中止dfs集羣
[atguigu@hadoop103 hadoop-2.7.2]$ sbin/stop-yarn.sh -- 中止yarn集羣
[atguigu@hadoop102 ~]$ zkstop.sh -- 中止zookeeper集羣
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/mr-jobhistory-daemon.sh stop historyserver -- 中止歷史服務器
方式一:
[atguigu@hadoop102 hive]$ bin/hive -- 啓動hive
方式二:
[atguigu@hadoop102 hive]$ bin/hiveserver2
[atguigu@hadoop102 hive]$ bin/beeline(在新的窗口中輸入)
Beeline version 1.2.1 by Apache Hive
beeline> !connect jdbc:hive2://hadoop102:10000(回車)
Connecting to jdbc:hive2://hadoop102:10000
Enter username for jdbc:hive2://hadoop102:10000: atguigu(回車)
Enter password for jdbc:hive2://hadoop102:10000: (直接回車)
Connected to: Apache Hive (version 1.2.1)
Driver: Hive JDBC (version 1.2.1)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://hadoop102:10000> show databases;
+----------------+--+
| database_name |
+----------------+--+
| default |
| hive_db2 |
+----------------+--+
CentOS6x
[atguigu@hadoop102 ~]$ sudo service mysqld restart
CentOS7x
[atguigu@hadoop102 ~]$ sudo systemctl restart mysqld.service
xxx.tsv 文件中的字段是以\t來分割的。
xxx.csv 文件中的字段是以逗號(,)來分割的。(comma:逗號)
collect_set(clo) 將多行數據聚合成一列數據,UDAF函數
concat_ws(separator, str1, str2,…) 聚合函數,UDAF函數
split((col),explode(col) 將一列數據拆成多行數據,UDTF函數
分桶算法
:id.hashCode % 4(桶數)Map集合key去重的原理和set集合去重原理
:先比較哈希值(本質是比較地址值,hashCode()),再比較所對應的具體值(equals())。
set集合存儲數據的本質是使用Map集合
來存儲的。
Map集合存儲數據的本質是使用數組
來存儲的。
數組存儲數據的本質是使用索引+值
來存儲的。
原文出處:https://www.cnblogs.com/chenmingjun/p/10463713.html