通過閱讀本文,可以讓你快速了解數倉如何分層街图,合理浇衬,實用。
筆者堅持原創(chuàng)餐济,根據實踐總結耘擂,希望對新手有所幫助。
分層案例
1.電信通訊
stage層 ->bdl層 ->analysis層
2.傳統(tǒng)金融/保險
ods層 ->pdm層 ->dm層
3.互聯網金融/電商
odl層 ->bdl層 ->idl層 ->adl層
盡管行業(yè)不同颤介,套路卻差不多梳星。本次借鑒互聯網分層模型,使用HIVE作為數據倉庫滚朵,搭建數據平臺冤灾。
專業(yè)術語
ODL層 (Operational Data Layer):操作數據層
外部數據什么樣,該層數據就是什么樣(關系型數據庫辕近、JSON格式等)
部分關系型數據可以直接轉IDL層
BDL層 (Base Data Layer):基礎數據層
ODL層經過簡單格式化解析后存儲到BDL層韵吨,常見于JSON日志格式的解析。
IDL層 (Interface Data Layer):接口層移宅,也稱主題表归粉,寬表
由BDL層經過去重椿疗、去噪、字典翻譯糠悼、空值轉化届榄,日期格式化、關聯JOIN倔喂、維度分析等清洗后的數據
如:用戶铝条、產品、綁卡席噩、訂單班缰、用戶行為等明細數據。
ADL層(Application Data Layer):應用層 悼枢,也稱數據集市
通常與需求對接埠忘,由IDL層基于某些維度的深度加工統(tǒng)計匯總等操作轉化而來,涉及到多個主題以及tmp數據之間的關聯JOIN后的結果馒索。
DIC層(Dictionary Data Layer):字典層
存儲一些諸如省莹妒、市、縣區(qū)域表双揪、渠道列表动羽、商品類目等等表數據,可以從數據源直接sqoop生成dic_xxx表渔期,也可以通過odl層轉化層dic_表运吓。
TMP層(Temporary Data Layer):臨時層
存儲一些中間計算結果
簡要說明
- 層次間的轉換沒必要循規(guī)蹈矩,按部就班疯趟,適當做到靈活拘哨,避免重復清洗浪費資源
- ODL層干凈的關系型數據可以直接轉換為IDL層數據,減少計算量
- ODL層側重與外部對接信峻,BDL層/TMP層/IDL層側重清洗倦青,IDL層和ADL層側重對外提供應用服務
- 層數太少不夠靈活,太多則在數據推翻重洗耗時盹舞,時間成本(一個坑)
- 數據源提供的數據越詳細越好产镐,避免后期大量重復的清洗工作。
此外踢步,大家可能經常聽到“星型模型”和“雪花模型”癣亚,簡單解釋下
(1)星型模型:事實表+維度表(區(qū)域、類目获印、性別...)等多表通過預先JOIN冗余到一張寬表里去述雾,常見IDL層。
(2)雪花模型:在計算的時候,才將事實表跟維度表做join玻孟。
現在一般都是采用(1)的模式唆缴,為什么呢? 預先計算黍翎,挺高性能面徽,避免后續(xù)重復計算。CPU和內存的資源永遠比磁盤空間寶貴的多匣掸。至于(2)的方式斗忌,有點就是靈活,不需要太多的重復清洗旺聚,但是性能不如(1).
建設思路
從需求出發(fā),逆推應用層ADL結構眶蕉,進而推導出它涉及的主題表IDL表結構砰粹,再推導可能涉及的基礎表BDL表結構,最后分析所需的數據源取自何處造挽。
需求包含“明確”需求和“潛在”需求碱璃。
開發(fā)步驟
- 創(chuàng)建ODL、BDL饭入、IDL嵌器、ADL層表結構(HQL)
- 確定數據抽取方案(增量或全量)
- 編寫sqoop腳本將data同步到ODL層
- 編寫ODL->BDL->IDL->ADL層ETL清洗腳本(HQL),注意:清洗的順序,時間
- 確保上一層的數據穩(wěn)定谐丢,減少對下一層的影響
- 編寫Hue workflow Ooize腳本
- 打通Kylin爽航、FineBI、Hive關系乾忱,實現數據可視化讥珍、可導出目標
- 將穩(wěn)定后所有腳本WIKI上保存一份
HIVE開發(fā)規(guī)范
Hive數據來源主要幾種:(1)關系型數據倉庫導入 (2)HDFS存儲的Log數據
(3)Flume sink過來的
數據的生產者:Ngnix log日志、業(yè)務系統(tǒng)埋點窄瘟、監(jiān)控日志衷佃、kafka 等
業(yè)務系統(tǒng)埋點的JSON格式 參考 《埋點-JSON格式通用》
表命名規(guī)范
ODL層:表名前綴 odl_
BDL層:表名前綴 bdl_
IDL層:表名前綴 idl_
ADL層:表名前綴 adl_
特別的
TMP表:表名前綴 tmp_ ,用于存儲中間計算、臨時的數據,配合前面4層計算
DIC表:表名前綴 dic_ ,用于存儲變化不大的字典信息蹄葱,如省份城市氏义、區(qū)域、類目等數據图云。
外部表和內部表
外部表
當需要通過Hive的HQL語句讀取HDFS數據時惯悠,需要建立外部表 create external “表名”,并指定數據在hdfs上的路徑 location 琼稻,完成這樣一個映射關系吮螺。
內部表
操HQL語句如同關系型數據一樣,創(chuàng)建表時不需要 external關鍵字
每個表增加個dt時間分區(qū)是個好習慣
dt 可以表示哪一天清洗的,也可以表示取自哪一天的全量數據或增量數據鸠补。
dt 可以讓數據可追溯萝风,哪天數據有誤可以根據dt抽取出來分析,可以重新計算紫岩。
insert into 和 insert overwrite
insert into 增量插入
insert overwrite 全量覆蓋规惰,已有的數據會消失,特別適合全量累計更新的需求泉蝌。
建議用如下語句歇万,
insert overwrite TABLE idl_event PARTITION (dt='${dt}')
select * from odl_event o where o.dt='${dt}'
idl_event表dt的含義是根據odl_event表達dt決定的,若dt只是一天的增量數據 勋陪,那么idl_event的dt也僅僅是一天的增量贪磺。若odl_event的dt表示全量數據,那么idl_event的dt诅愚,每一個dt都是表示全量數據寒锚。
示例場景:當發(fā)現T日的增量數據清洗有誤,需重清洗违孝,則可以使用上面的語句刹前,避免T日以前的數據也被覆蓋掉。
boolean類型
關系型數據庫中場景的boolean類型值位1或0 以及一些非boolean類型有時也用0,1,2..等數值表示雌桑,不夠直觀,容易誤解
建議boolean類型在數倉中用字符串 “Y” 或 “N” 表示 喇喉,未知的用“U”表示(unknow)
金額單位
建議以元為單位(最終展示),避免從“元——>分” 校坑,“分—->元” 頻繁轉化拣技。
建議使用decimal ,而非double 撒踪,避免一些計算導致精度不準確
日期格式
建議是 YYYY-MM-DD HH:MM:SS 过咬、YYYY-MM-DD或 YYYYMMDD格式
有些LOG日志可能是Long類型的時間戳,按日期排序去重挺好的制妄,但在這個在IDL層以上要轉化為上條建議的格式掸绞。
一些商業(yè)智能分析工具,如tableau耕捞、帆軟等對YYYY-MM-DD格式的支持更好衔掸,可根據日期計算換算成-周、月報等俺抽。
字段“type”和status
一張表可能有多個status或type字段敞映,命名規(guī)范 xxx_status、xxx_type
表字段名稱
odl->bdl->idl->adl 每一層相同含義的字段名稱盡量保持一致磷斧,避免理解上帶來誤解振愿。
針對一些涉及KV鍵值對的字段捷犹,如性別 sex=1 男 ,sex=2 女 ,需要新增一個字段 例:sex_value=男 導出報表時冕末,查詢改字段萍歉。
合適需要創(chuàng)建分區(qū)partition
分區(qū)一般按照時間分區(qū),如按天 档桃、按小時 枪孩;當hive需要查詢hdfs時,要創(chuàng)建跟hdfs相同的分區(qū)類型才可以訪問其數據藻肄。
數據傾斜與優(yōu)化
有時候跑Hive時蔑舞,會發(fā)現job跑到99%時會停止在那里,說明在Map階段嘹屯,執(zhí)行快的job在等待少了執(zhí)行慢的job攻询,然后在繼續(xù)reduce 。
往往是因為語句使用了distinct 州弟,group by 或者太多的join操作導致的蜕窿。
評估不同維度數據的差異是否很大,若是很大可以根據業(yè)務拆分多個語句跑
某些字段計算時呆馁,歸屬哪一層
比如,用戶的“首次綁卡時間”毁兆,“最后一次登錄時間” 浙滤,“首次購買時間”,“最近一次購買時間” 這里涉及到了【用戶】-【綁卡信息】-【訂單信息】-【登錄信息】多個實體
气堕,就要考慮到BDL/IDL/ADL中的哪一層計算的問題.
清洗使用HIVE纺腊,查詢請借助Impala
Impala查詢的速度,是Hive的幾十倍茎芭,一般1~5秒內可以范圍揖膜。
Impala不適合清洗,因為語法跟hive還是有很大一部分差異的
Impala比較耗內存
一般商業(yè)智能分析工具如tableau梅桩、帆軟獲取其它的都支持Impala
以下是本人的經歷:
《一個大數據小白到架構的經歷》
《Hive 25億數據性能優(yōu)化總結》