map階段的優化
作業會通過input的目錄產生乙個或多個map任務。
a) 假設input目錄下有1個檔案a,大小為780m,那麼hadoop會將該檔案a分隔成7個塊(6個128m的塊和1個12m的塊),從而產生7個map數
b) 假設input目錄下有3個檔案a,b,c,大小分別為10m,20m,130m,那麼hadoop會分隔成4個塊(10m,20m,128m,2m),從而產生4個map數
即,如果檔案大於塊大小(128m),那麼會拆分,如果小於塊大小,則把該檔案當成乙個塊。
如果小檔案數量非常多,而且本身的處理邏輯時間遠小於map任務的啟動和初始化時間,可通過下面的引數來控制map的數量
mapred.min.split.size:指的是資料的最小分割單元大小;min的預設值是1b
mapred.max.split.size:指的是資料的最大分割單元大小;max的預設值是256mb
通過調整max可以起到調整map數的作用,減小max可以增加map數,增大max可以減少map數。
需要提醒的是,直接調整mapred.map.tasks這個引數是沒有效果的。
map數量越多越好嗎?是不是保證每個map處理接近檔案塊大小?
這得根據情況來分析,假設:
有一張窄表,大小為120m,300w條資料,表裡有2個字段(user_id,age)
另一張寬表,大小為12m,1w條資料,但是表字段有30多個
兩個檔案大小差不多,但是map處理資料量差距卻非常大。第一張表處理邏輯如果很複雜,乙個map去處理的話肯定更耗時了。
這時需要根據情況來減少或增加map數量
通過以下方法來在map執行前合併小檔案,減少map數:
set mapred.max.split.size=128000000; -- 每個map最大輸入大小
set mapred.min.split.size.per.node=100000000; -- 乙個節點上map最小分割,決定結點間是否合併
set mapred.min.split.size.per.rack=100000000; -- 乙個機架下map最小分割,決定機架間是否合併
set hive.input.format=org.apache.hadoop.hive.ql.io.combinehiveinputformat; -- 執行map前進行小檔案合併, 合併的大小由`mapred.max.split.size`引數決定
100000000表示100m, 前面三個引數確定合併檔案塊的大小,大於檔案塊大小128m的,按照128m來分隔,小於128m,大於100m的,按照100m來分隔,把那些小於100m的(包括小檔案和分隔大檔案剩下的),進行合併
reduce階段優化
reduce優化比map優化更重要
hive是如何確定reduce的數量
不指定reduce個數的情況下,hive會猜測確定乙個reduce個數,基於以下兩個設定:
hive.exec.reducers.bytes.per.reducer
(每個reduce任務處理的資料量,預設為1000^3=1g)
hive.exec.reducers.max
(每個任務最大的reduce數,預設為999)
計算reducer數的公式很簡單n=min(引數2,總輸入資料量/引數1)
即,如果reduce的輸入(map的輸出)總大小不超過1g,那麼只會有乙個reduce任務;
hive.exec.reducers.bytes.per.reducer
這個設定在資料傾斜中會用到,在出現資料傾斜時,乙個reduce處理不了的可以分成多個reduce來處理,但是需要將reduce處理完的結果進行彙總。
set hive.exec.reducers.bytes.per.reducer=500000000; (按大小 每個500m)
set mapred.reduce.tasks = 15; (直接設定reduce數量)
reduce數量不是越多越好
同map一樣,啟動和初始化reduce也會消耗時間和資源;
另外,有多少個reduce,就會有多少個輸出檔案,如果生成了很多個小檔案,那麼如果這些小檔案作為下乙個任務的輸入,則也會出現小檔案過多的問題;
什麼情況下只有乙個reduce
很多時候你會發現任務中不管資料量多大,不管你有沒有設定調整reduce個數的引數,任務中一直都只有乙個reduce任務;其實只有乙個reduce任務的情況,除了資料量小於hive.exec.reducers.bytes.per.reducer
引數值的情況外,還有以下原因:
hive的優化
資料傾斜處理
症狀 傾斜度
定位出現資料傾斜時,對資料進行分桶取樣,看哪個key的數量遠大於其他key的數量
萬能方法
set hive.groupby.skewindata = true
控制生成兩個mr job,第乙個mr job map讓key隨機分發到reducer,而不是同樣的key分發到同乙個reducer,然後reduce做聚合,減少某些key值條數過多某些key條數過小造成的資料傾斜問題。把map端聚合放到了reduce端,增加了reducer新的開銷,大多數情況效果並不好。
大小表關聯
方法small_table join big_table
大大表關聯
大大表關聯(業務削弱)
思路當天登入的使用者其實很少
方法
select /*+ mapjoin(t12)*/ *
from dw_log t11
join (
select /*+ mapjoin(t)*/ t1.*
from (
select distinct user_id from dw_log --group by user_id
) tjoin dw_user t1
on t.user_id = t1.user_id
) t12
on t11.user_id = t12.user_id
聚合時存在大量特殊值
方法:
select cast(count(distinct user id) +1 as bigint) as user_cnt
from tab_a
where user id is not null and user id <> ''
參考:
Hadoop大資料 Hive初識
hadoop提供了大資料的通用解決方案,比如儲存提供了hdfs,計算提供了mapreduce思想。但是想要寫出mapreduce演算法還是比較繁瑣的,對於開發者來說,需要了解底層的hadoop api。如果不是開發者想要使用mapreduce就會很困難.另一方面,大部分的開發者都有使用sql的經驗。...
Hadoop大資料 Hive初識
hadoop提供了大資料的通用解決方案,比如儲存提供了hdfs,計算提供了mapreduce思想。但是想要寫出mapreduce演算法還是比較繁瑣的,對於開發者來說,需要了解底層的hadoop api。如果不是開發者想要使用mapreduce就會很困難.另一方面,大部分的開發者都有使用sql的經驗。...
Hadoop系列001 大資料概論
大資料 big data 指無法在一定時間範圍內用常規軟體工具進行捕捉 管理和處理的資料集合,是需要新處理模式才能具有更強的決策力 洞察發現力和流程優化能力的海量 高增長率和多樣化的資訊資產。最小的基本單位是bit,按順序給出所有單位 bit byte kb mb gb tb pb eb zb yb...