作者: 永洪BI??來源: 永洪科技??時間:2020年01月07日
我們知道數據分析的第一步是準備數據,所以在前面的課程里,我們介紹了元數據(Yonghong BI課程系列之概念:元數據),今天這篇文章,主要介紹大數據量組合數據集在永洪中的應用實例:Mapsidejoin。
什么是Mapsidejoin?按照字面意思,Mapsidejoin就是M—節點—組合 。在了解Mapsidejoin之前,首先我們要了解一下MapReduce模型以及產品的四個節點CNMR的作用,通過MapReduce模型中,Mapsidejoin和Reducesidejoin的對比,了解在大數據量數據集進行組合時,Mapsidejoin的優點。
Client Node —C節點是客戶端訪問節點,客戶通過訪問C節點來提交任務。
Naming Node —N節點相當于集群的大腦,除了監控集群其他節點外,還要收集客戶通過C節點提交的任務進行分配等等。
Map Node — M節點是存儲數據文件的節點
Reduce Node —R節點是用來做匯總計算的計算
百度百科對MapReduce的定義感覺還是比較全面的,簡單的概括一下:MapReduce是一個基于集群的計算平臺,是一個簡化分布式編程的計算框架,是一個將分布式計算抽象為Map和Reduce兩個階段的編程模型。而Yonghong在進行組合數據集計算時用到的就是MapReduce模型。
適用場景:多M節點的分布式集群,大數據量數據的組合包括大表join小表,大表join大表。
在MapReduce模型中,對于組合計算可以分為Map-side-join 和Reduce-side-join兩種,下面用一個例子簡單介紹一下:
假設我們有兩張表:表1人員表為大表,表2地區表為小表,如下圖所示:
我們想通過id把表1的name和表2的Address連接起來 ,那么就需要以id為連接列,做inner join, 連接對應的id為id=1,id=2,id=3,id=4。
假如現在我們的集群里面有Map1和Map2兩個Map節點,那么當我們將表1和表2入集市以后,經過數據的拆分存儲,我們可能會出現以下情況:
? 情況1:可以進行Mapsidejoin
如上圖所示,經過拆分后的表1和表2,連接列id=1-4 對應的數據存放在了同一個節點,在join時,Map節點會檢測連接列數據是否已經完成對應,如果此時數據對應后就可以在Map節點上進行join,Map節點將join后的結果發送給Reduce節點,Reduce節點將結果進行匯總計算就可以了。
? 情況2:不能進行Mapsidejoin時會進行Reducesidejoin
上圖所示, 經過拆分存儲后的數據顯示表1的id1,2存放在了Map1節點;而表2的id1,2 存放在了Map2 節點上面;這個時候在join時Map節點檢測到對應的數據不在同一個節點上,就會將所有的數據拿到Reduce節點重新進行全量的join。
以上兩種情況簡單的說明了Mapsidejoin 和 Reducesidejoin。
Map端join的好處是可以提前過濾掉join中需要排除的大量數據,會減少數據的傳輸,因此Mapsidejoin 適用于大數據量join的場景。
Reduce端做join優點是比較靈活,缺點是需要做大量數據傳輸和整個join過程都比較耗時,因此Reducesidejoin適用于小數據量的場景。
此外, 由于當數據量巨大時,做join是非常消耗資源的,對于非Mapsidejoin的形式,無論是直連數據庫壓到數據庫做join,還是數據集市的形式去做Reducesidejoin,都會對節點造成極大壓力,容易造成產品很卡的情況,再嚴重就會造成OOM,宕機等。所以我們需要使用Mapsidejoin來規避這種場景, 當數據量大的時候,我們可以部署多個M節點,通過將數據先導入集市,存放在集群中的多個M節點,然后在M節點上面進行計算來實現Mapsidejoin,這樣能把C,R節點的壓力平均分到M節點上面,解決大數據量join可能帶來的使用壓力,讓資源的利用更加高效。
那么我們怎么實現Mapsidejoin呢 ?如何保證數據經過拆分后,連接列對應的數據一定存放在同一個Map節點上面呢?下面介紹永洪Mapsidejoin的兩種實現方式。
事實表——維度表
適用場景(大表join小表)
在分布式系統中,當有星形數據(一個大表,若干個小表)需要join的時候,可以將小表的數據復制到每個Map節點,執行Mapsidejoin, 而無須到Reduce節點進行連接操作,從而提升表連接的效率。
在MPP集市中,我們將大表以普通的增量導入形式入集市,將所有小表在增量導入時勾選維度表的形式,如下圖所示:
此時勾選維度表的小表會全量生成在每一個Map節點。
以上面表1人員表,表2地區表的為例:表1增量導入正常拆分,表2以增量導入維度表形式入集市。
如圖所示,此時在每一個M節點上,因為表2全量存儲,所以表1和表2對應的id數據就一定能在同一個M節點找到。
但是事實表——維度表的形式也有局限性,比如兩個以上的大表做join時,就需要將其中的一個或多個大表,存放到每一個M節點上,大數據量的大表進行維度表存儲本來就會加大資源消耗,而且大表作為維度表,無法壓到內存中進行計算,因此無法使用Mapsidejoin。
所以針對這種情況,我們采取分片列來支持大表join大表的使用場景。
分片列
適用場景(大表join大表)
在8.5.1版本之前,我們只能用維度表join事實表的形式去做Mapsidejoin,在一些用戶場景中,無法提前進行數據表關聯做成寬表模型入集市,同時也不滿足Mapsidejoin(或broadcast join)計算的要求,因此需要在集市中做分布式join的計算支持。
具體場景有:
1)業務上需要,比如:部分匯總后再進行關聯,某時間段內產品銷售額大于特定值時的產品報修批次分布;特定值進行關聯,選擇某個時間段里面最后出現的數據和另外的表關聯;自關聯,本月數據和上月數據關聯計算等等;這些場景下(一般是雪花模型或更復雜)如果提前join會導致數據膨脹,從而產生非常多的冗余數據,但實際使用時因為有過濾條件則不會產生太多數據;
2)數據量較大的事實表需要頻繁增量更新,且全量數據join成寬表入集市的時間開銷太大;
3)自服務場景下,是否要關聯表,以及關聯什么字段存在不確定性,需要保留原始細節表來進行自助查詢。
分片列的Mapsidejoin實現邏輯其實和上面情況1的圖片類似。
我們通過增量導入分片列的形式將表1和表2的關聯列使用hash算法,保證兩張表的id對應的數據經過拆分后一定會存儲在同一個Map節點上面,這樣經過拆分的大表就可以壓到內存中計算。
1、將需要組合的大表以增量導入的形式入集市,同時需要勾選分片列屬性,選擇分片列為鏈接列。比如表1在增量導入集市時要勾選分片列為id ,表2也需要同樣的操作。
2、將生成的數據集市數據集進行組合,Map節點在檢測數據時會自動使用Mapsidejoin形式連接。
一定要記住使用Mapsidejoin的前提是分布式集群多M節點且大數據量數據集市的數據集做join。
最后我們用一張圖片來簡單的回顧一下Mapsidejoin的兩種形式。
大表jion大表用分片列
大表join小表用事實表——維度表
?
永洪BI
更敏捷、更快速、更強大