什么叫數(shù)據(jù)倉庫胆描?如何構(gòu)建數(shù)據(jù)倉庫瞬雹?
數(shù)據(jù)倉庫是一個面向主題的(Subject Oriented)悄晃、集成的(Integrate)、相對穩(wěn)定的(Non-Volatile)褥蚯、反映歷史變化(Time Variant)的數(shù)據(jù)集合挚冤,它用于支持企業(yè)或組織的決策分析處理。
數(shù)據(jù)倉庫是為了便于多維分析和多角度展現(xiàn)而將數(shù)據(jù)按特定的模式進(jìn)行存儲所建立起來的關(guān)系型數(shù)據(jù)庫赞庶,它的數(shù)據(jù)基于OLTP源系統(tǒng)训挡。
首先,用于支持決策歧强,面向分析型數(shù)據(jù)處理澜薄,它不同于企業(yè)現(xiàn)有的操作型數(shù)據(jù)庫;
其次摊册,對多個異構(gòu)的數(shù)據(jù)源有效集成肤京,集成后按照主題進(jìn)行了重組,并包含歷史數(shù)據(jù)茅特,而且存放在數(shù)據(jù)倉庫中的數(shù)據(jù)一般不再修改忘分;
數(shù)倉分層
引入數(shù)據(jù)層(ODS)、公共維度模型層(CDM)和應(yīng)用數(shù)據(jù)層(APP),其中公共維度模型層包括明細(xì)數(shù)據(jù)層(DWD和匯總數(shù)據(jù)層(DWS)
公共維度模型層(CDM):存放明細(xì)事實數(shù)據(jù)白修、維表數(shù)據(jù)及公共指標(biāo)匯總數(shù)據(jù),其中明細(xì)事實數(shù)據(jù)妒峦、維表數(shù)據(jù)一般根據(jù)ODS層數(shù)據(jù)加工生成:公共指標(biāo)匯總數(shù)據(jù)一般根據(jù)維表數(shù)據(jù)和明細(xì)事實數(shù)據(jù)加工生成。
CDM層又細(xì)分為DWD層和DWS層,分別是明細(xì)數(shù)據(jù)層和匯總數(shù)據(jù)層,采用維度模型方法作為理論基礎(chǔ),更多地采用一些維度退化手法,將維度退化至事實表中,減少事實表和維表的關(guān)聯(lián),提高明細(xì)數(shù)據(jù)表的易用性:同時在匯總數(shù)據(jù)層,加強(qiáng)指標(biāo)的維度退化,采取更多的寬表化手段構(gòu)建公共指標(biāo)數(shù)據(jù)層,提升公共指標(biāo)的復(fù)用性,減少重復(fù)加工兵睛。
應(yīng)用數(shù)據(jù)層(APP):存放數(shù)據(jù)產(chǎn)品個性化的統(tǒng)計指標(biāo)數(shù)據(jù),根據(jù)CDM層與ODS層加工生成肯骇。提供差異化的數(shù)據(jù)服務(wù)、滿足業(yè)務(wù)方的需求祖很;在該層級實現(xiàn)報表(數(shù)易笛丙、郵件報表)、數(shù)據(jù)產(chǎn)品假颇、或者其他分析主題的需要
粒度
用于確定某一事實表中的行表示什么胚鸯,是業(yè)務(wù)最小活動單元或不同維度組合,即業(yè)務(wù)細(xì)節(jié)程度拆融。
?維度建模:
維度建模從分析決策的需求出發(fā)構(gòu)建模型,為分析需求服務(wù)啊终,因此 它重點關(guān)注用戶如何更快速地完成需求分析镜豹,同時具有較好的大規(guī)模復(fù) 雜查詢的響應(yīng)性能。其典型的代表是星形模型蓝牲,以及在一些特殊場景下 使用的雪花模型趟脂。其設(shè)計分為以下幾個步驟:
1.選擇需要進(jìn)行分析決策的業(yè)務(wù)過程。業(yè)務(wù)過程可以是單個業(yè)務(wù)事 件例衍,比如交易的支付昔期、退款等已卸;也可以是某個事件的狀態(tài),比如 當(dāng)前的賬戶余額等硼一;還可以是一系列相關(guān)業(yè)務(wù)事件組成的業(yè)務(wù)流 程累澡,具體需要看我們分析的是某些事件發(fā)生情況,還是當(dāng)前狀態(tài)般贼, 或是事件流轉(zhuǎn)效率愧哟。· 2.選擇粒度哼蛆。在事件分析中蕊梧,我們要預(yù)判所有分析需要細(xì)分的程度,從而決定選擇的粒度腮介。粒度是維度的一個組合肥矢。· 3.識別維表叠洗。選擇好粒度之后甘改,就需要基于此粒度設(shè)計維表,包括 維度屬性惕味,用于分析時進(jìn)行分組和篩選楼誓。·4.選擇事實名挥。確定分析需要衡量的指標(biāo)疟羹。
星型模型
星型模型主要是維表和事實表,以事實表為中心禀倔,所有維度直接關(guān)聯(lián)在事實表上榄融,呈星型分布。
雪花模型
雪花模型救湖,在星型模型的基礎(chǔ)上愧杯,維度表上又關(guān)聯(lián)了其他維度表。
星座模型
星座模型鞋既,是對星型模型的擴(kuò)展延伸力九,多張事實表共享維度表。
數(shù)據(jù)倉庫邑闺、數(shù)據(jù)中臺跌前、數(shù)據(jù)湖的理解
https://mp.weixin.qq.com/s?__biz=Mzg3NjIyNjQwMg==&mid=2247484122&idx=1&sn=5cd900a39725a822b31b45be0e23a4eb&chksm=cf3430d7f843b9c166010933c06a112439d490d81a7b746699d1e8fa75467ae4f3c409826684&scene=21#wechat_redirect
司機(jī)畫像
在數(shù)據(jù)資源管理層之上是系統(tǒng)的核心,畫像標(biāo)簽生產(chǎn)層陡舅,包含ETL抵乓、IDM、數(shù)據(jù)聚合模塊、標(biāo)簽提取模塊和一些算法策略工具灾炭;
抽象業(yè)務(wù)行為茎芋,司機(jī)行為以多時間切片聚合,全量聚合(最早蜈出、最晚)田弥、最近n天聚合
為什么要分層的思考?
空間換時間掏缎。通過建設(shè)多層次的數(shù)據(jù)模型供用戶使用皱蹦,避免用戶直接使用操作型數(shù)據(jù),可以更高效的訪問數(shù)據(jù)眷蜈。? 把復(fù)雜問題簡單化沪哺。講一個復(fù)雜的任務(wù)分解成多個步驟來完成,每一層只處理單一的步驟酌儒,比較簡單和容易理解辜妓。而且便于維護(hù)數(shù)據(jù)的準(zhǔn)確性,當(dāng)數(shù)據(jù)出現(xiàn)問題之后忌怎,可以不用修復(fù)所有的數(shù)據(jù)籍滴,只需要從有問題的步驟開始修復(fù)。? 便于處理業(yè)務(wù)的變化榴啸。隨著業(yè)務(wù)的變化孽惰,只需要調(diào)整底層的數(shù)據(jù),對應(yīng)用層對業(yè)務(wù)的調(diào)整零感知.
如何評價一個數(shù)據(jù)倉庫的好壞鸥印?
數(shù)據(jù)準(zhǔn)確性勋功、時效性、健壯性库说。
各層級表的訪問量狂鞋,公共匯總層,減少數(shù)據(jù)庫在響應(yīng)查詢時必須執(zhí)行的工作量潜的,快速響應(yīng)用戶的查詢骚揍,同時減少不同用戶訪問明細(xì)數(shù)據(jù)帶來的結(jié)果不一致問題。
緩慢變化維
維度的屬性并不是靜態(tài)的啰挪,它會隨著時間發(fā)生緩慢的變化
第一種處理方式:重寫維度值信不,始終取最新數(shù)據(jù)
第二張:插入新的維度行,維度變化前的事實和過去的維度值關(guān)聯(lián)
第三:添加維度列亡呵,新舊類目
必須使用代理鍵作為每個維表的主鍵抽活,用于處理緩慢變化維
不使用代理鍵,每天保留一份全量數(shù)據(jù)(滴滴)
拉鏈表
拉鏈歷史表政己,既能滿足反應(yīng)數(shù)據(jù)的歷史狀態(tài)酌壕,又可以最大程度的節(jié)省存儲;
據(jù)量有點大,表中某些字段有變化歇由,但是呢變化的頻率也不是很高卵牍,業(yè)務(wù)需求呢又需要統(tǒng)計這種變化狀態(tài),每天全量一份呢沦泌,有點不太現(xiàn)實糊昙,不僅浪費了存儲空間,有時可能業(yè)務(wù)統(tǒng)計也有點麻煩谢谦,這時释牺,拉鏈表的作用就提現(xiàn)出來了,既節(jié)省空間回挽,又滿足了需求没咙。一般在數(shù)倉中通過增加begin_date,en_date來表示,如下例千劈,后兩列是start_date和end_date.
begin_date表示該條記錄的生命周期開始時間祭刚,end_date表示該條記錄的生命周期結(jié)束時間;
end_date = ‘9999-12-31’表示該條記錄目前處于有效狀態(tài)墙牌;
如果查詢當(dāng)前所有有效的記錄涡驮,則select * from order_his where dw_end_date = ‘9999-12-31′
如果查詢2016-08-21的歷史快照,則select * from order_his where begin_date <= ‘2016-08-21′ and end_date >= ‘2016-08-21’
事實表有哪幾種類型喜滨?
事務(wù)事實表 記錄的是事務(wù)層面的事實捉捅,保留的是最原子的數(shù)據(jù),每個事務(wù)一條記錄虽风。
周期快照事實表? 以有規(guī)律性的時間間隔來記錄事實棒口,如余額、庫存焰情、層級等陌凳,記錄的是這個時間段內(nèi)的一些聚集事實值或狀態(tài)度量。
一些狀態(tài)度量内舟,需要聚集與之相關(guān)的事務(wù)才能進(jìn)行識別計算合敦,累計支付金額;直接使用操作型系統(tǒng)的數(shù)據(jù)作為周期快照事實表的數(shù)據(jù)源進(jìn)行加工验游,星級充岛,增量更新
累積快照事實表?用來跟蹤實體的一系列業(yè)務(wù)過程的進(jìn)展情況。訂單表 特點:數(shù)據(jù)不斷更新耕蝉、多業(yè)務(wù)過程時間崔梗,實現(xiàn)方式:全量表、以業(yè)務(wù)實體的結(jié)束時間分區(qū)
聚集型事實表
order by垒在,sort by蒜魄,cluster by,distribute by的區(qū)別
1)order by是全局排序,排序過程在一個reduce中進(jìn)行谈为,在數(shù)據(jù)量較大時就會很慢
2)sort by是局部排序旅挤,排序結(jié)果在同一個reduce中使有序的
3)distribute by是將數(shù)據(jù)按照字段劃分到一個reduce中,一般與sort by連用進(jìn)行分組排序的作用
4)cluster by除具有distribute by功能外還具有sort by的功能
order by優(yōu)化:
1)開啟嚴(yán)格模式伞鲫,order by之后添加limit子句
2)利用sort by粘茄,在每個reduce中先排序取出top項,再把預(yù)處理結(jié)果order by輸出
hive中內(nèi)部表和外部表的區(qū)別
1)在創(chuàng)建表的時候秕脓,內(nèi)部表是將數(shù)據(jù)移動到數(shù)據(jù)倉庫指向的路徑柒瓣,外部表僅記錄數(shù)據(jù)所在的路徑,不對數(shù)據(jù)的位置做任何改變吠架。
2)在刪除表的時候芙贫,內(nèi)部表會將元數(shù)據(jù)和數(shù)據(jù)都刪除,外部表只刪除元數(shù)據(jù)傍药。
列轉(zhuǎn)行屹培、行轉(zhuǎn)列
1)列轉(zhuǎn)行:lateral view explode(split('column_name',','))作為一個新表
2)行轉(zhuǎn)列:concat_ws(',',collect_set(column_name))
無事實的事實表
?在多維數(shù)據(jù)倉庫建模中,有一種事實表叫做“無事實的事實表”怔檩。普通事實表中褪秀,通常會保存若干維度外鍵和多個數(shù)字型度量,度量是事實表的關(guān)鍵所在薛训。然而在無事實的事實表中沒有這些度量值媒吗,只有多個維度外鍵。表面上看乙埃,無事實事實表是沒有意義的闸英,因為作為事實表,畢竟最重要的就是度量介袜。但在數(shù)據(jù)倉庫中甫何,這類事實表有其特殊用途。無事實的事實表通常用來跟蹤某種事件或者說明某些活動的范圍遇伞。
代駕數(shù)倉主題域
司機(jī)辙喂、乘客、交易(派單鸠珠、訂單巍耗、費用)、財務(wù)域渐排、公共域(圍欄信息)炬太、營銷域(券的發(fā)放、使用)
?同一指標(biāo)不同需求方給出的統(tǒng)計口徑不一樣
udf
x='[{"a":0,"b":1,"c":2},{"a":0,"b":1,"c":2},{"a":0,"b":1,"c":2}]'
parm="a"
x=eval(x)
for i in range(len(x)):
? ? print(x[i].get(parm))
滴滴數(shù)倉指標(biāo)體系建設(shè)方法論和搭建實踐
https://www.sohu.com/a/419032959_411876
hadoop2 Mappers and Reducers 內(nèi)存設(shè)置
https://my.oschina.net/OttoWu/blog/814585
Hadoop MapReduce執(zhí)行過程詳解(帶hadoop例子)
https://blog.csdn.net/weixin_33937778/article/details/91798914?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase
hr面試?????????https://zhuanlan.zhihu.com/p/87908851
python udf??????https://blog.csdn.net/qq_26937525/article/details/54136317
flink? ? ?????https://www.bilibili.com/video/av75625853?p=1
打字練習(xí)??https://www.keybr.com/
排序算法?https://www.cnblogs.com/bobo-zhang/p/10574925.html
hive字符串函數(shù)?https://www.iteblog.com/archives/1639.html
如何在實際業(yè)務(wù)中合理評估渠道價值驯耻?????https://cloud.tencent.com/developer/article/1049995
1.6.2 Hive和數(shù)據(jù)庫比較
Hive?和數(shù)據(jù)庫除了擁有類似的查詢語言亲族,再無類似之處炒考。
1)數(shù)據(jù)存儲位置
Hive?存儲在?HDFS?。數(shù)據(jù)庫將數(shù)據(jù)保存在塊設(shè)備或者本地文件系統(tǒng)中霎迫。
2)數(shù)據(jù)更新
Hive中不建議對數(shù)據(jù)的改寫票腰。而數(shù)據(jù)庫中的數(shù)據(jù)通常是需要經(jīng)常進(jìn)行修改的,
3)執(zhí)行延遲
Hive?執(zhí)行延遲較高女气。數(shù)據(jù)庫的執(zhí)行延遲較低。當(dāng)然测柠,這個是有條件的炼鞠,即數(shù)據(jù)規(guī)模較小,當(dāng)數(shù)據(jù)規(guī)模大到超過數(shù)據(jù)庫的處理能力的時候轰胁,Hive的并行計算顯然能體現(xiàn)出優(yōu)勢谒主。
4)數(shù)據(jù)規(guī)模
Hive支持很大規(guī)模的數(shù)據(jù)計算;數(shù)據(jù)庫可以支持的數(shù)據(jù)規(guī)模較小赃阀。
1.6.3 內(nèi)部表和外部表
1)管理表:當(dāng)我們刪除一個管理表時霎肯,Hive也會刪除這個表中數(shù)據(jù)。管理表不適合和其他工具共享數(shù)據(jù)榛斯。
2)外部表:刪除該表并不會刪除掉原始數(shù)據(jù)观游,刪除的是表的元數(shù)據(jù)
1.6.4 4個By區(qū)別
1)Sort?By:分區(qū)內(nèi)有序;
2)Order By:全局排序驮俗,只有一個Reducer懂缕;
3)Distrbute By:類似MR中Partition,進(jìn)行分區(qū)王凑,結(jié)合sort by使用搪柑。
4)?Cluster By:當(dāng)Distribute by和Sorts by字段相同時,可以使用Cluster by方式索烹。Cluster by除了具有Distribute by的功能外還兼具Sort by的功能工碾。但是排序只能是升序排序,不能指定排序規(guī)則為ASC或者DESC百姓。
1.6.5 窗口函數(shù)
RANK() 排序相同時會重復(fù)渊额,總數(shù)不會變
DENSE_RANK() 排序相同時會重復(fù),總數(shù)會減少
ROW_NUMBER() 會根據(jù)順序計算
1)?OVER():指定分析函數(shù)工作的數(shù)據(jù)窗口大小垒拢,這個數(shù)據(jù)窗口大小可能會隨著行的變而變化
2)CURRENT ROW:當(dāng)前行
3)n?PRECEDING:往前n行數(shù)據(jù)
4)?n?FOLLOWING:往后n行數(shù)據(jù)
5)UNBOUNDED:起點端圈,UNBOUNDED PRECEDING?表示從前面的起點, UNBOUNDED?FOLLOWING表示到后面的終點
6)?LAG(col,n):往前第n行數(shù)據(jù)
7)LEAD(col,n):往后第n行數(shù)據(jù)
8)?NTILE(n):把有序分區(qū)中的行分發(fā)到指定數(shù)據(jù)的組中子库,各個組有編號舱权,編號從1開始,對于每一行仑嗅,NTILE返回此行所屬的組的編號宴倍。注意:n必須為int類型张症。
1.6.6 自定義UDF、UDTF
在項目中是否自定義過UDF鸵贬、UDTF函數(shù)俗他,以及用他們處理了什么問題,及自定義步驟阔逼?
1)自定義過兆衅。
2)用UDF函數(shù)解析公共字段;用UDTF函數(shù)解析事件字段嗜浮。
自定義UDF:繼承UDF羡亩,重寫evaluate方法
?????? 自定義UDTF:繼承自GenericUDTF,重寫3個方法:initialize(自定義輸出的列名和類型)危融,process(將結(jié)果返回forward(result))畏铆,close
為什么要自定義UDF/UDTF,因為自定義函數(shù)吉殃,可以自己埋點Log打印日志辞居,出錯或者數(shù)據(jù)異常,方便調(diào)試.
舉例:
Json數(shù)組 提取指定key的value
x='[{"a":0,"b":1,"c":2},{"a":0,"b":1,"c":2},{"a":0,"b":1,"c":2}]'
parm="a"
x=eval(x)?執(zhí)行字符串表達(dá)式 這里返回一個字典列表
for i in range(len(x)):
????? if parm in x[i].keys():
?????? print(x[i].get(parm))
1.6.7 Hive優(yōu)化
1)MapJoin
如果不指定MapJoin或者不符合MapJoin的條件蛋勺,那么Hive解析器會將Join操作轉(zhuǎn)換成Common Join瓦灶,即:在Reduce階段完成join。容易發(fā)生數(shù)據(jù)傾斜抱完∫邪幔可以用MapJoin把小表全部加載到內(nèi)存在map端進(jìn)行join,避免reducer處理乾蛤。
2)行列過濾
列處理:在SELECT中每界,只拿需要的列,如果有家卖,盡量使用分區(qū)過濾眨层,少用SELECT *。
行處理:在分區(qū)剪裁中上荡,當(dāng)使用外關(guān)聯(lián)時趴樱,如果將副表的過濾條件寫在Where后面,那么就會先全表關(guān)聯(lián)酪捡,之后再過濾叁征。
3)列式存儲
orc?當(dāng)查詢只需要少數(shù)幾個字段的時候,能大大減少讀取的數(shù)據(jù)量
行存儲 textfile sequencefile 查詢滿足條件的一整行數(shù)據(jù)的時候逛薇,其余值都在相鄰的地方捺疼。
4)采用分區(qū)技術(shù)
5)合理設(shè)置Map數(shù)
(1)通常情況下,作業(yè)會通過input的目錄產(chǎn)生一個或者多個map任務(wù)永罚。
主要的決定因素有:input的文件總個數(shù)啤呼,input的文件大小卧秘,集群設(shè)置的文件塊大小。
(2)是不是map數(shù)越多越好官扣?
答案是否定的翅敌。如果一個任務(wù)有很多小文件(遠(yuǎn)遠(yuǎn)小于塊大小128m),則每個小文件也會被當(dāng)做一個塊惕蹄,用一個map任務(wù)來完成蚯涮,而一個map任務(wù)啟動和初始化的時間遠(yuǎn)遠(yuǎn)大于邏輯處理的時間,就會造成很大的資源浪費卖陵。而且遭顶,同時可執(zhí)行的map數(shù)是受限的。
(3)是不是保證每個map處理接近128m的文件塊赶促,就高枕無憂了?
答案也是不一定挟炬。比如有一個127m的文件鸥滨,正常會用一個map去完成,但這個文件只有一個或者兩個小字段谤祖,卻有幾千萬的記錄婿滓,如果map處理的邏輯比較復(fù)雜,用一個map任務(wù)去做粥喜,肯定也比較耗時凸主。
針對上面的問題2和3,我們需要采取兩種方式來解決:即減少map數(shù)和增加map數(shù)额湘;
6)小文件進(jìn)行合并
在Map執(zhí)行前合并小文件卿吐,減少Map數(shù):CombineHiveInputFormat具有對小文件進(jìn)行合并的功能(系統(tǒng)默認(rèn)的格式)。HiveInputFormat沒有對小文件合并功能锋华。
7)合理設(shè)置Reduce數(shù)
Reduce個數(shù)并不是越多越好
(1)過多的啟動和初始化Reduce也會消耗時間和資源嗡官;
(2)另外,有多少個Reduce毯焕,就會有多少個輸出文件衍腥,如果生成了很多個小文件,那么如果這些小文件作為下一個任務(wù)的輸入纳猫,則也會出現(xiàn)小文件過多的問題婆咸;
在設(shè)置Reduce個數(shù)的時候也需要考慮這兩個原則:處理大數(shù)據(jù)量利用合適的Reduce數(shù);使單個Reduce任務(wù)處理數(shù)據(jù)量大小要合適芜辕;
8)常用參數(shù)
// 輸出合并小文件
SET hive.merge.mapfiles = true; -- 默認(rèn)true尚骄,在map-only任務(wù)結(jié)束時合并小文件
SET hive.merge.mapredfiles = true; -- 默認(rèn)false,在map-reduce任務(wù)結(jié)束時合并小文件
SET hive.merge.size.per.task = 268435456; -- 默認(rèn)256M
SET hive.merge.smallfiles.avgsize = 16777216; -- 當(dāng)輸出文件的平均大小小于16m該值時侵续,啟動一個獨立的map-reduce任務(wù)進(jìn)行文件merge
9)開啟map端combiner(不影響最終業(yè)務(wù)邏輯)
set hive.map.aggr=true乖仇;
10)壓縮(選擇快的)
設(shè)置map端輸出憾儒、中間結(jié)果壓縮。(不完全是解決數(shù)據(jù)傾斜的問題乃沙,但是減少了IO讀寫和網(wǎng)絡(luò)傳輸起趾,能提高很多效率)
壓縮方式為Snappy,特點速度快警儒,缺點無法切分(可以回答在鏈?zhǔn)組R中训裆,Reduce端輸出使用bzip2壓縮,以便后續(xù)的map任務(wù)對數(shù)據(jù)進(jìn)行split)
11)開啟JVM重用
1.6.8 Hive解決數(shù)據(jù)傾斜方法
1)數(shù)據(jù)傾斜長啥樣蜀铲?
2)怎么產(chǎn)生的數(shù)據(jù)傾斜边琉?
不同數(shù)據(jù)類型關(guān)聯(lián)產(chǎn)生數(shù)據(jù)傾斜
情形:比如用戶表中user_id字段為int,log表中user_id字段既有string類型也有int類型记劝。當(dāng)按照user_id進(jìn)行兩個表的Join操作時变姨。
后果:處理此特殊值的reduce耗時;只有一個reduce任務(wù)默認(rèn)的Hash操作會按int型的id來進(jìn)行分配厌丑,這樣會導(dǎo)致所有string類型id的記錄都分配到一個Reducer中定欧。
解決方式:把數(shù)字類型轉(zhuǎn)換成字符串類型
select * from users a
left outer join logs b
on a.usr_id =cast(b.user_id as string)
3)解決數(shù)據(jù)傾斜的方法?
(1)group by
注:group by 優(yōu)于distinct group
解決方式:采用sum() group by的方式來替換count(distinct)完成計算怒竿。
(2)mapjoin
(3)開啟數(shù)據(jù)傾斜時負(fù)載均衡
set hive.groupby.skewindata=true;
思想:就是先隨機(jī)分發(fā)并處理砍鸠,再按照key group by來分發(fā)處理。
操作:當(dāng)選項設(shè)定為true耕驰,生成的查詢計劃會有兩個MRJob伟阔。
第一個MRJob 中般此,Map的輸出結(jié)果集合會隨機(jī)分布到Reduce中喷舀,每個Reduce做部分聚合操作嘱蛋,并輸出結(jié)果,這樣處理的結(jié)果是相同的GroupBy Key有可能被分發(fā)到不同的Reduce中媒抠,從而達(dá)到負(fù)載均衡的目的示启;
第二個MRJob再根據(jù)預(yù)處理的數(shù)據(jù)結(jié)果按照GroupBy Key分布到Reduce中(這個過程可以保證相同的原始GroupBy Key被分布到同一個Reduce中),最后完成最終的聚合操作领舰。
點評:它使計算變成了兩個mapreduce夫嗓,先在第一個中在 shuffle 過程 partition 時隨機(jī)給 key 打標(biāo)記,使每個key 隨機(jī)均勻分布到各個 reduce 上計算冲秽,但是這樣只能完成部分計算舍咖,因為相同key沒有分配到相同reduce上。
所以需要第二次的mapreduce,這次就回歸正常 shuffle,但是數(shù)據(jù)分布不均勻的問題在第一次mapreduce已經(jīng)有了很大的改善锉桑,因此基本解決數(shù)據(jù)傾斜排霉。因為大量計算已經(jīng)在第一次mr中隨機(jī)分布到各個節(jié)點完成。
(4)控制空值分布
將為空的key轉(zhuǎn)變?yōu)樽址与S機(jī)數(shù)或純隨機(jī)數(shù)民轴,將因空值而造成傾斜的數(shù)據(jù)分不到多個Reducer攻柠。
注:對于異常值如果不需要的話球订,最好是提前在where條件里過濾掉,這樣可以使計算量大大減少
實踐中瑰钮,可以使用case when對空值賦上隨機(jī)值冒滩。此方法比直接寫is not null更好,因為前者job數(shù)為1浪谴,后者為2.
使用case when實例1:
select userid, name fromuser_info a
join (
select
case when userid isnull? then? cast (rand(47)* 100000 as int )
else userid end from user_read_log
) b? on a.userid = b.userid
使用case when實例2:
select?'${date}' as thedate,
??? a.search_type,
??? a.query,
??? a.category,
??? a.cat_name,
??? a.brand_id,
??? a.brand_name,
??? a.dir_type,
??? a.rewcatid,
??? a.new_cat_name,
??? a.new_brand_id,
??? f.brand_name as new_brand_name,
??? a.pv,
??? a.uv,
??? a.ipv,
??? a.ipvuv,
??? a.trans_amt,
??? a.trans_num,
??? a.alipay_uv
from fdi_search_query_cat_qp_temp a
left outer join brand f
on?f.pt='${date}000000' and case whena.new_brand_id is null then concat('hive',rand() ) else a.new_brand_id end =f.brand_id;
如果上述的方法還不能解決开睡,比如當(dāng)有多個JOIN的時候,建議建立臨時表苟耻,然后拆分HIVE SQL語句篇恒。
1.6.9 用的是動態(tài)分區(qū)嗎?動態(tài)分區(qū)的底層原理是什么凶杖?
a. 靜態(tài)分區(qū)與動態(tài)分區(qū)的主要區(qū)別在于靜態(tài)分區(qū)是手動指定胁艰,而動態(tài)分區(qū)是通過數(shù)據(jù)來進(jìn)行判斷。
b. 詳細(xì)來說智蝠,靜態(tài)分區(qū)的列實在編譯時期腾么,通過用戶傳遞來決定的;動態(tài)分區(qū)只有在 SQL 執(zhí)行時才能決定寻咒。
c. 動態(tài)分區(qū)是基于查詢參數(shù)的位置去推斷分區(qū)的名稱哮翘,從而建立分區(qū)
26. Hive里邊字段的分隔符用的什么颈嚼?為什么用\t毛秘?有遇到過字段里邊有\(zhòng)t的情況嗎,怎么處理的阻课?
hive 默認(rèn)的字段分隔符為ascii碼的控制符\001(^A),建表的時候用fieldsterminated by '\001'
遇到過字段里邊有\(zhòng)t的情況叫挟,自定義InputFormat,替換為其他分隔符再做后續(xù)處理