0x01
今天看靠,由于公司要進行新老數(shù)據(jù)倉庫的遷移来庭,于是順便接手了其中一部分的工作焚辅,其實大部分遷移工作都比較簡單,就是把從ods層-dw層-dm層-sh展示層中涉及到舊倉庫的表替換成新倉庫的表誓军,并且檢查其中字段的差異性袱讹,并進行相應的操作疲扎。于是擼起袖子開工昵时。
0x02
- 前期的進展很順利,很快就完成了幾張表的遷移椒丧,心想著按這個進度壹甥,不到一個小時就能完成了。Orz
- 在進行到第五張表的遷移時壶熏,發(fā)現(xiàn)很久沒有完成句柠,于是檢查了日志,發(fā)現(xiàn)卡在了reduce階段棒假,從60%作用開始溯职,基本上每隔10分鐘左右進度才增加1%。
- 遇到這種情況帽哑,第一反應就是發(fā)生了數(shù)據(jù)傾斜谜酒,于是馬上進行數(shù)據(jù)源的排查,在這里先說明一下查詢語句主體妻枕,大致如下
select xxx from t1 left join on t2 where t1.sid = t2.sid left join t3 on t1.uid = t3.uid
僻族。其中t2和t3均已經(jīng)進行了去重和選定分區(qū)的處理粘驰。 - t1以及t2的數(shù)據(jù)量在百萬級別,t3在億級別作用述么。然后對t1進行了count(distinct uid)后蝌数,發(fā)現(xiàn)了異常數(shù)據(jù) null的量在千萬級別,于是采取了直接剔除null的解決方案度秘,心想這個應該就不會進行數(shù)據(jù)傾斜了顶伞,于是再次運行腳本,然后等待敷钾,結果出乎我的意料枝哄,這次沒有卡在60%,而是卡在了65%阻荒,淚崩啊挠锥。
- 再次檢查日志,發(fā)現(xiàn)reduce個數(shù)只有一個侨赡,心想大概是hive自動判斷reduce個數(shù)不準確蓖租,于是手動強制設定了reduce的個數(shù)
set mapred.reduce.tasks=800;
。再一次運行羊壹,等待蓖宦,60%--70%--80%--90%--95%...,這下終于正常了油猫。...99%--99%--99%--99%...稠茂,在看到一連串的99%不斷刷新的同時,我終于接受了還有錯誤的事實情妖。 - 到底哪里出錯了呢睬关,按說數(shù)據(jù)量也并不是特別大呀,想了想毡证,還有一個辦法电爹,就是使用
hive.groupby.skewindata=true;
來進行當有數(shù)據(jù)傾斜時進行負載均衡,其實理性告訴我料睛,和這個關系不大丐箩,但是沒辦法了呀,只能試一下了恤煞。結果不出我所料屎勘,還是卡在了99%。 - 還有半小時就到飯點了居扒,怎么辦概漱,這時候同事對我隨口提了一句,檢查一下數(shù)據(jù)類型苔货,說不定是數(shù)據(jù)類型不一致造成的呢犀概。"不應該呀"立哑,我嘀咕著,抱著死馬當活馬醫(yī)的態(tài)度姻灶,我看了一些表結構铛绰,發(fā)現(xiàn)還真不一樣,t1的是bigint产喉,而t2和t3的是string捂掰。但是我記得hive有自動隱式轉換機制的呀,為了驗證我的觀點曾沈,我進行了
select cast(1010000001000390061 as bigint) = cast(1010000001000390061 as string)
查詢这嚣,結果就是返回true,應該不是這個原因塞俱。是的姐帚。 - 但是也想不到別的辦法了,于是再去吃飯之前障涯,我還是提交了這個微小的改動罐旗,
cast(t1.sid as string) = t2.sid
,在吃飯的過程中,我一直在想解決的辦法唯蝶,吃完飯回來九秀,奇跡發(fā)生了,居然就是這個原因U澄摇9难选! - 突然想起來征字,之前有過一次都弹,好像也是數(shù)據(jù)類型的原因,在使用join時柔纵,對兩個bigint類型和string類型進行等值操作時缔杉,乍一看锤躁,操作沒問題搁料,可是仔細一看,返回的數(shù)據(jù)不對啊系羞。當時也沒注意這個細節(jié)郭计。
- 難道是超出了bigint范圍?在查詢了
select cast(10010000001000390061 as bigint)
后椒振,驚奇的發(fā)現(xiàn)居然返回了9223372036854775807昭伸,這下明白了,應該是在join時澎迎,由于t3的uid字段超出了bigint的范圍庐杨,從而使得最后的連接后數(shù)據(jù)量劇增选调,想一下,百萬 * 百萬 * 億 灵份,大概有10的20次方仁堪,難怪卡在了99%。
0xff
- 回顧這一次填坑之旅填渠,不僅意識到了不能完全依賴于平臺提供的便利功能弦聂,而疏忽了其背后原理性的東西。如自動轉換類型的原理氛什,以及相關的限制莺葫。
- 對于不同層的表的維度字段的定義,盡量保證維度字段的類型保持一致枪眉,不然有可能會出現(xiàn)一些奇怪的問題捺檬,比如我這次遇到的由于超出范圍而造成自動轉換的結果不準確的bug。
- 在遇到問題遲遲不能解決的時候贸铜,不妨問問身邊的人欺冀,俗話說的好,當局者迷萨脑,旁觀者清嘛隐轩。Orz