一妥凳、故障情景
基于Hive的數(shù)據(jù)倉(cāng)庫(kù)中需要做一張累積快照表竟贯,記錄了客戶發(fā)生各個(gè)行為的具體日期,比如激活日期逝钥、注冊(cè)日期屑那、申請(qǐng)日期、創(chuàng)建訂單日期等等艘款。
這張表需要以激活日期作為分區(qū)時(shí)間持际,便于業(yè)務(wù)查詢。
激活日期將近500個(gè)日期哗咆,在一次性將所有數(shù)據(jù)全量插入目標(biāo)分區(qū)的時(shí)候所有reduce報(bào)OOM选酗。
二、解決過(guò)程
首先增加reduce端的內(nèi)存岳枷,set mapreduce.reduce.java.opts = -Xmx3072m;set mapreduce.reduce.memory.mb = 3072呜叫;最后將內(nèi)存設(shè)置到集群最高內(nèi)存空繁,仍然報(bào)OOM。
再分析源數(shù)據(jù)的分類朱庆,發(fā)現(xiàn)源數(shù)據(jù)存在以前的測(cè)試數(shù)據(jù)盛泡,這樣會(huì)造成有的分區(qū)日期只有一條數(shù)據(jù),有的分區(qū)天數(shù)有幾十萬(wàn)數(shù)據(jù)娱颊,數(shù)據(jù)存在嚴(yán)重的傾斜傲诵。
解決方法有兩種。
第一種在HQL末尾加上distribute by和sort by箱硕,或者cluster by拴竹。如下:
insert overwrite table loan_f_milestone partition(day)
select *,
to_date(atv_tim)
from loan_f_milestone_tmp12
distribute by to_date(atv_tim)
sort by to_date(atv_tim)
--cluster by to_date(atv_tim)
distribute by按照指定的字段將數(shù)據(jù)劃分到不同的輸出reduce中,可以保證每個(gè)reduce處理的數(shù)據(jù)范圍不重疊剧罩,每個(gè)分區(qū)內(nèi)的數(shù)據(jù)是沒(méi)有排序的栓拜。
sort by保證一個(gè)reduce內(nèi)的數(shù)據(jù)按照指定字段排序。
cluster by除了有distribute by的功能,還有sort by的功能幕与,所以最終的結(jié)果是每個(gè)reduce處理的數(shù)據(jù)范圍不重疊挑势,而且每個(gè)reduce內(nèi)的數(shù)據(jù)按照指定字段排序,而且可以做到全局排序啦鸣。
所以第二種方式是設(shè)置set hive.optimize.sort.dynamic.partition=true潮饱;會(huì)將動(dòng)態(tài)分區(qū)字段全局排序。