Hive分組排序

系統環境

Linux Ubuntu 16.04

jdk-7u75-linux-x64

hive-1.1.0-cdh5.4.5

hadoop-2.6.0-cdh5.4.5

mysql-5.7.24

相關知識

Hive中支持多種分組操作:Order by、Sort by、Group by、Distribute by、Cluster by等

(1)Hive中的Order by和傳統Sql中的Order by一樣,對查詢結果做全局排序,會新啓動一個Job進行排序,會把所有數據放到同一個Reduce中進行處理,不管數據多少,不管文件多少,都啓用一個Reduce進行處理。如果指定了hive.mapred.mode=strict(默認值是nonstrict),這時就必須指定limit來限制輸出條數,原因是:所有的數據都會在同一個Reducer端進行,數據量大的情況下可能不出結果,那麼在這樣的嚴格模式下,必須指定輸出的條數。

(2)Sort by是局部排序,會在每個Reduce端做排序,單個Reduce出來的數據是有序的,假設我設置了3個Reduce,那麼這3個Reduce就會生成三個文件,每一個文件都會按Sort by後設置的條件排序,但是當這3個文件數據合在一起就不一定有序了,一般情況下可以先進行Sort by局部排序完成後,再進行全局排序,就會提高不少效率。

(3)Group by是分組查詢,一般配合聚合函數一起使用,Group by有一個原則,就是Select後面的所有列中,沒有使用聚合函數的列,必須出現在Group by後面。

(4)Hive中的Distribute by是控制在Map端如何拆分數據給Reduce端的。按照指定的字段對數據劃分到不同的Reduce輸出文件中,默認是採用Hash算法。對於Distribute by進行測試,一定要分配多Reduce進行處理,否則無法看到Distribute by的效果。

(5)Cluster by除了具有Distribute by的功能外還兼具Sort by的功能,相當於Distribute by+ Sort by的結合,但是排序只能是倒敘排序,不能指定排序規則爲ASC或者DESC。

任務內容

1.全局排序Order by與局部排序Sort by的用法,以及各自適用的場景。

2.分組查詢Group by的應用場景與基本語法。

3.Cluster by與Distribute by和Sort by的關係及操作。

任務步驟

1.首先檢查Hadoop相關進程,是否已經啓動。若未啓動,切換到/apps/hadoop/sbin目錄下,啓動Hadoop。

jps  
cd /apps/hadoop/sbin  
./start-all.sh  

2.然後開啓Mysql,用於存放Hive的元數據。(密碼:zhangyu)

sudo service mysql start  

3.切換到/data/hive4目錄下,如不存在需提前創建hive4文件夾。

mkdir /data/hive4  
cd /data/hive4  

4.使用wget命令,下載http://192.168.1.100:60000/allfiles/hive4中的文件。

wget http://192.168.1.100:60000/allfiles/hive4/goods_visit
wget http://192.168.1.100:60000/allfiles/hive4/order_items
wget http://192.168.1.100:60000/allfiles/hive4/buyer_favorite

5.在終端命令行界面,直接輸入Hive命令,啓動Hive命令行。

hive  

Order by的演示

1.在Hive中創建一個goods_visit表,有goods_id ,click_num 2個字段,字符類型都爲string,以‘\t’爲分隔符。

create table goods_visit(goods_id string,click_num int)
row format delimited fields terminated by '\t'  stored as textfile;

在這裏插入圖片描述
創建完成,查詢一下。

show tables;  

在這裏插入圖片描述
2.將本地 /data/hive4下的表goods_visit中數據導入到Hive中的goods_visit表中。

load data local inpath'/data/hive4/goods_visit' into table goods_visit;

在這裏插入圖片描述
3.使用Order by對商品點擊次數從大到小排序,並通過limit取出10條數據。

select * from goods_visit order by click_num desc limit 10;

在這裏插入圖片描述
在這裏插入圖片描述

Sort by 的演示

1.爲演示Sort by效果 ,我將Reduce個數設置爲三個,命令如下:

set mapred.reduce.tasks=3;  

2.爲某電商創建一個訂單明細表,名爲order_items,包含item_id 、order_id 、goods_id 、goods_number 、shop_price 、goods_price 、goods_amount 七個字段,字符類型都爲string,以‘\t’爲分隔符。

create table order_items(item_id string,order_id string,goods_id string,goods_number string,
shop_price string,goods_price string,goods_amount string)
row format delimited fields terminated by '\t'  stored as textfile;

在這裏插入圖片描述
3.將本地/data/hive4/下的表order_items中數據導入到Hive中的order_items表中。

load data local inpath '/data/hive4/order_items' into table order_items;

在這裏插入圖片描述
4.按商品ID(goods_id)進行排序。

select * from order_items sort by goods_id;  

在這裏插入圖片描述

Group by的演示

1.爲某電商創建一個買家收藏夾表,名爲buy_favorite,有buyer_id 、goods_id 、dt 三個字段,字符類型都爲string,以‘\t’爲分隔符。

create table buyer_favorite(buyer_id string,goods_id string,dt string)
row format delimited fields terminated by '\t'  stored as textfile;

在這裏插入圖片描述
2.將本地/data/hive4/下的表buyer_favorite中數據導入到Hive中的buyer_favorite表中。

load data local inpath '/data/hive4/buyer_favorite' into table buyer_favorite;

在這裏插入圖片描述
3.按dt分組查詢每天的buyer_id數量。

select dt,count(buyer_id) from buyer_favorite group by dt;

在這裏插入圖片描述

Distribute by的演示

1.爲演示Distribute by效果 ,我將Reduce個數設置爲三個,命令如下:

set mapred.reduce.tasks=3;  

2.使用買家收藏夾表,按用戶ID(buyer_id)做分發(distribute by),輸出到本地/data/hive4/out中。

insert overwrite local directory '/data/hive4/out' select * from buyer_favorite distribute by buyer_id;

在這裏插入圖片描述
3.切換到linux本地窗口,查看目錄/data/hive4/out下的文件。

cd /data/hive4/out  
ls  

在這裏插入圖片描述
數據按buyer_id分發到三個文件中。

Cluster by 的演示

Cluster by除了具有Distribute by的功能外還兼具Sort by的功能,相當於Distribute by+ Sort by的結合,但是排序只能是倒敘排序,不能指定排序規則爲ASC或者DESC。

1.將Reduce個數設置爲3個。

set mapred.reduce.tasks=3;  

2.按buyer_id將buyer_favorite分發成三個文件,並按buyer_id排序。

select * from buyer_favorite cluster by buyer_id;

在這裏插入圖片描述
在這裏插入圖片描述

Order by 與Sort by 對比

Order by的查詢結果是全部數據全局排序,它的Reduce數只有一個,Reduce任務繁重,因此數據量大的情況下將會消耗很長時間去執行,而且可能不會出結果,因此必須指定輸出條數。

Sort by是在每個Reduce端做排序,它的Reduce數可以有多個,它保證了每個Reduce出來的數據是有序的,但多個Reduce出來的數據合在一起未必是有序的,因此在Sort by做完局部排序後,還要再做一次全局排序,相當於先在小組內排序,然後只要將各小組排序即可,在數據量大的情況下,可以提升不少的效率。

Distribute by 與Group by 對比

Distribute by是通過設置的條件在Map端拆分數據給Reduce端的,按照指定的字段對數據劃分到不同的輸出Reduce文件中。

Group by它的作用是通過一定的規則將一個數據集劃分成若干個小的區域,然後針對若干個小區域進行數據處理,例如某電商想統計一年內商品銷售情況,可以使用Group by將一年的數據按月劃分,然後統計出每個月熱銷商品的前十名。

兩者相比,都是按Key值劃分數據,都使用Reduce操作,唯一不同的是Distribute by只是單純的分散數據,而Group by把相同Key的數據聚集到一起,後續必須是聚合操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章