溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

hive中怎么實現(xiàn)全排序

發(fā)布時間:2021-08-12 14:47:30 來源:億速云 閱讀:123 作者:Leah 欄目:云計算

hive中怎么實現(xiàn)全排序,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

全排序

hive的排序關(guān)鍵字是SORT BY,它有意區(qū)別于傳統(tǒng)數(shù)據(jù)庫的ORDER BY也是為了強調(diào)兩者的區(qū)別–SORT BY只能在單機范圍內(nèi)排序。

1.1.1     例1

set mapred.reduce.tasks=2;

原值

select cookie_id,page_id,id fromc02_clickstat_fatdt1

where cookie_idIN('1.193.131.218.1288611279693.0','1.193.148.164.1288609861509.2')

1.193.148.164.1288609861509.2  113181412886099008861288609901078194082403      684000005

1.193.148.164.1288609861509.2  127001128860563972141288609859828580660473      684000015

1.193.148.164.1288609861509.2  113181412886099165721288609915890452725326      684000018

1.193.131.218.1288611279693.0  01c183da6e4bc50712881288611540109914561053      684000114

1.193.131.218.1288611279693.0  01c183da6e4bc22412881288611414343558274174      684000118

1.193.131.218.1288611279693.0  01c183da6e4bc50712881288611511781996667988      684000121

1.193.131.218.1288611279693.0  01c183da6e4bc22412881288611523640691739999      684000126

1.193.131.218.1288611279693.0  01c183da6e4bc50712881288611540109914561053      684000128

hive> select cookie_id,page_id,id fromc02_clickstat_fatdt1 where

cookie_idIN('1.193.131.218.1288611279693.0','1.193.148.164.1288609861509.2')

SORT BY COOKIE_ID,PAGE_ID;

SORT排序后的值

1.193.131.218.1288611279693.0           684000118      01c183da6e4bc22412881288611414343558274174      684000118

1.193.131.218.1288611279693.0           684000114      01c183da6e4bc50712881288611540109914561053      684000114

1.193.131.218.1288611279693.0           684000128      01c183da6e4bc50712881288611540109914561053      684000128

1.193.148.164.1288609861509.2           684000005       113181412886099008861288609901078194082403      684000005

1.193.148.164.1288609861509.2           684000018      113181412886099165721288609915890452725326      684000018

1.193.131.218.1288611279693.0           684000126       01c183da6e4bc22412881288611523640691739999      684000126

1.193.131.218.1288611279693.0           684000121      01c183da6e4bc50712881288611511781996667988      684000121

1.193.148.164.1288609861509.2           684000015      127001128860563972141288609859828580660473      684000015

select cookie_id,page_id,id fromc02_clickstat_fatdt1

where cookie_idIN('1.193.131.218.1288611279693.0','1.193.148.164.1288609861509.2')

ORDER BY PAGE_ID,COOKIE_ID;

1.193.131.218.1288611279693.0           684000118       01c183da6e4bc22412881288611414343558274174      684000118

1.193.131.218.1288611279693.0           684000126      01c183da6e4bc22412881288611523640691739999      684000126

1.193.131.218.1288611279693.0           684000121      01c183da6e4bc50712881288611511781996667988      684000121

1.193.131.218.1288611279693.0           684000114      01c183da6e4bc50712881288611540109914561053      684000114

1.193.131.218.1288611279693.0           684000128      01c183da6e4bc50712881288611540109914561053      684000128

1.193.148.164.1288609861509.2           684000005      113181412886099008861288609901078194082403      684000005

1.193.148.164.1288609861509.2           684000018      113181412886099165721288609915890452725326      684000018

1.193.148.164.1288609861509.2           684000015       127001128860563972141288609859828580660473      684000015

可以看到SORT和ORDER排序出來的值不一樣。一開始我指定了2個reduce進(jìn)行數(shù)據(jù)分發(fā)(各自進(jìn)行排序)。結(jié)果不一樣的主要原因是上述查詢沒有reduce key,hive會生成隨機數(shù)作為reduce key。這樣的話輸入記錄也隨機地被分發(fā)到不同reducer機器上去了。為了保證reducer之間沒有重復(fù)的cookie_id記錄,可以使用DISTRIBUTE BY關(guān)鍵字指定分發(fā)key為cookie_id。

select cookie_id,country,id,page_id,id fromc02_clickstat_fatdt1 where cookie_idIN('1.193.131.218.1288611279693.0','1.193.148.164.1288609861509.2')  distribute by cookie_id SORT BYCOOKIE_ID,page_id;

1.193.131.218.1288611279693.0           684000118       01c183da6e4bc22412881288611414343558274174      684000118

1.193.131.218.1288611279693.0           684000126      01c183da6e4bc22412881288611523640691739999      684000126

1.193.131.218.1288611279693.0           684000121       01c183da6e4bc50712881288611511781996667988      684000121

1.193.131.218.1288611279693.0           684000114      01c183da6e4bc50712881288611540109914561053      684000114

1.193.131.218.1288611279693.0           684000128      01c183da6e4bc50712881288611540109914561053      684000128

1.193.148.164.1288609861509.2           684000005      113181412886099008861288609901078194082403      684000005

1.193.148.164.1288609861509.2           684000018      113181412886099165721288609915890452725326      684000018

1.193.148.164.1288609861509.2           684000015      127001128860563972141288609859828580660473      684000015

1.1.2     例2

CREATE TABLE if not exists t_order(

id int, -- 訂單編號

sale_id int, -- 銷售ID

customer_id int, -- 客戶ID

product _id int, -- 產(chǎn)品ID

amount int -- 數(shù)量

) PARTITIONED BY (ds STRING);

在表中查詢所有銷售記錄,并按照銷售ID和數(shù)量排序:

set mapred.reduce.tasks=2;

Select sale_id, amount from t_order

Sort by sale_id, amount;

這一查詢可能得到非期望的排序。指定的2個reducer分發(fā)到的數(shù)據(jù)可能是(各自排序):

Reducer1:

Sale_id | amount

0 | 100

1 | 30

1 | 50

2 | 20

Reducer2:

Sale_id | amount

0 | 110

0 | 120

3 | 50

4 | 20

使用DISTRIBUTE BY關(guān)鍵字指定分發(fā)key為sale_id。改造后的HQL如下:

set mapred.reduce.tasks=2;

Select sale_id, amount from t_order

Distribute by sale_id

Sort by sale_id, amount;

這樣能夠保證查詢的銷售記錄集合中,銷售ID對應(yīng)的數(shù)量是正確排序的,但是銷售ID不能正確排序,原因是hive使用hadoop默認(rèn)的HashPartitioner分發(fā)數(shù)據(jù)。

這就涉及到一個全排序的問題。解決的辦法無外乎兩種:

1.) 不分發(fā)數(shù)據(jù),使用單個reducer:

set mapred.reduce.tasks=1;

這一方法的缺陷在于reduce端成為了性能瓶頸,而且在數(shù)據(jù)量大的情況下一般都無法得到結(jié)果。但是實踐中這仍然是最常用的方法,原因是通常排序的查詢是為了得到排名靠前的若干結(jié)果,因此可以用limit子句大大減少數(shù)據(jù)量。使用limit n后,傳輸?shù)絩educe端(單機)的數(shù)據(jù)記錄數(shù)就減少到n* (map個數(shù))。

2.) 修改Partitioner,這種方法可以做到全排序。這里可以使用Hadoop自帶的TotalOrderPartitioner(來自于Yahoo!的TeraSort項目),這是一個為了支持跨reducer分發(fā)有序數(shù)據(jù)開發(fā)的Partitioner,它需要一個SequenceFile格式的文件指定分發(fā)的數(shù)據(jù)區(qū)間。如果我們已經(jīng)生成了這一文件(存儲在/tmp/range_key_list,分成100個reducer),可以將上述查詢改寫為

set mapred.reduce.tasks=100;

set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner;

settotal.order.partitioner.path=/tmp/ range_key_list;

Select sale_id, amount from t_order

Cluster by sale_id

Sort by amount;

有很多種方法生成這一區(qū)間文件(例如hadoop自帶的o.a.h.mapreduce.lib.partition.InputSampler工具)。這里介紹用Hive生成的方法,例如有一個按id有序的t_sale表:

CREATE TABLE if not exists t_sale (

id int,

name string,

loc string

);

則生成按sale_id分發(fā)的區(qū)間文件的方法是:

create external tablerange_keys(sale_id int)

row format serde

'org.apache.hadoop.hive.serde2.binarysortable.BinarySortableSerDe'

stored as

inputformat

'org.apache.hadoop.mapred.TextInputFormat'

outputformat

'org.apache.hadoop.hive.ql.io.HiveNullValueSequenceFileOutputFormat'

location '/tmp/range_key_list';

insert overwrite table range_keys

select distinct sale_id

from source t_salesampletable(BUCKET 100 OUT OF 100 ON rand()) s

sort by sale_id;

生成的文件(/tmp/range_key_list目錄下)可以讓TotalOrderPartitioner按sale_id有序地分發(fā)reduce處理的數(shù)據(jù)。區(qū)間文件需要考慮的主要問題是數(shù)據(jù)分發(fā)的均衡性,這有賴于對數(shù)據(jù)深入的理解。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI