溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Hadoop中的兩表是什么

發(fā)布時間:2021-12-09 15:17:35 來源:億速云 閱讀:141 作者:iii 欄目:云計算

這篇文章主要介紹“Hadoop中的兩表是什么”,在日常操作中,相信很多人在Hadoop中的兩表是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Hadoop中的兩表是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

Common Join

最為普通的join策略,不受數(shù)據(jù)量的大小影響,也可以叫做reduce side join ,最沒效率的一種join 方式. 它由一個mapreduce job 完成.

首先將大表和小表分別進行map 操作, 在map shuffle 的階段每一個map output key 變成了table_name_tag_prefix + join_column_value , 但是在進行partition 的時候它仍然只使用join_column_value 進行hash.

每一個reduce 接受所有的map 傳過來的split , 在reducce 的shuffle 階段,它將map output key 前面的table_name_tag_prefix 給舍棄掉進行比較. 因為reduce 的個數(shù)可以由小表的大小進行決定,所以對于每一個節(jié)點的reduce 一定可以將小表的split 放入內(nèi)存變成hashtable. 然后將大表的每一條記錄進行一條一條的比較.

Map Join

Map Join 的計算步驟分兩步,將小表的數(shù)據(jù)變成hashtable廣播到所有的map 端,將大表的數(shù)據(jù)進行合理的切分,然后在map 階段的時候用大表的數(shù)據(jù)一行一行的去探測(probe) 小表的hashtable. 如果join key 相等,就寫入HDFS.

map join 之所以叫做map join 是因為它所有的工作都在map 端進行計算.

hive 在map join 上做了幾個優(yōu)化:

  • hive 0.6 的時候默認認為寫在select 后面的是大表,前面的是小表, 或者使用 /*+mapjoin(map_table) */ 提示進行設定. hive 0.7 的時候這個計算是自動化的,它首先會自動判斷哪個是小表,哪個是大表,這個參數(shù)由(hive.auto.convert.join=true)來控制. 然后控制小表的大小由(hive.smalltable.filesize=25000000L)參數(shù)控制(默認是25M),當小表超過這個大小,hive 會默認轉化成common join. 你可以查看HIVE-1642.

    首先小表的Map 階段它會將自己轉化成MapReduce Local Task ,然后從HDFS 取小表的所有數(shù)據(jù),將自己轉化成Hashtable file 并壓縮打包放入DistributedCache 里面.

    目前hive 的map join 有幾個限制,一個是它打算用BloomFilter 來實現(xiàn)hashtable , BloomFilter 大概比hashtable 省8-10倍的內(nèi)存, 但是BloomFilter 的大小比較難控制.

    現(xiàn)在DistributedCache 里面hashtable默認的復制是3份,對于一個有1000個map 的大表來說,這個數(shù)字太小,大多數(shù)map 操作都等著DistributedCache 復制.

     

    Bucket Map Join

    hive 建表的時候支持hash 分區(qū)通過指定clustered by (col_name,xxx ) into number_buckets buckets 關鍵字.

    當連接的兩個表的join key 就是bucket column 的時候,就可以通過

    hive.optimize.bucketmapjoin= true

    來控制hive 執(zhí)行bucket map join 了, 需要注意的是你的小表的number_buckets 必須是大表的倍數(shù). 無論多少個表進行連接這個條件都必須滿足.(其實如果都按照2的指數(shù)倍來分bucket, 大表也可以是小表的倍數(shù),不過這中間需要多計算一次,對int 有效,long 和string 不清楚)

    Bucket Map Join 執(zhí)行計劃分兩步,第一步先將小表做map 操作變成hashtable 然后廣播到所有大表的map端,大表的map端接受了number_buckets 個小表的hashtable并不需要合成一個大的hashtable,直接可以進行map 操作,map 操作會產(chǎn)生number_buckets 個split,每個split 的標記跟小表的hashtable 標記是一樣的, 在執(zhí)行projection 操作的時候,只需要將小表的一個hashtable 放入內(nèi)存即可,然后將大表的對應的split 拿出來進行判斷,所以其內(nèi)存限制為小表中最大的那個hashtable 的大小.

    Bucket Map Join 同時也是Map Side Join 的一種實現(xiàn),所有計算都在Map 端完成,沒有Reduce 的都被叫做Map Side Join ,Bucket 只是hive 的一種hash partition 的實現(xiàn),另外一種當然是值分區(qū).

    create table a  (xxx) partition by (col_name)

    不過一般hive 中兩個表不一定會有同一個partition key, 即使有也不一定會是join key. 所以hive 沒有這種基于值的map side join, hive 中的list partition 主要是用來過濾數(shù)據(jù)的而不是分區(qū). 兩個主要參數(shù)為(hive.optimize.cp = true 和 hive.optimize.pruner=true)

    hadoop 源代碼中默認提供map side join 的實現(xiàn), 你可以在hadoop 源碼的src/contrib/data_join/src 目錄下找到相關的幾個類.  其中TaggedMapOutput 即可以用來實現(xiàn)hash 也可以實現(xiàn)list , 看你自己決定怎么分區(qū). Hadoop Definitive Guide 第8章關于map side join 和side data distribution 章節(jié)也有一個例子示例怎樣實現(xiàn)值分區(qū)的map side join.

     

    Sort Merge Bucket Map Join

    Bucket Map Join 并沒有解決map join 在小表必須完全裝載進內(nèi)存的限制, 如果想要在一個reduce 節(jié)點的大表和小表都不用裝載進內(nèi)存,必須使兩個表都在join key 上有序才行,你可以在建表的時候就指定sorted by join key 或者使用index 的方式.

    set hive.optimize.bucketmapjoin = true;

    set hive.optimize.bucketmapjoin.sortedmerge = true;

    set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;

    Bucket columns == Join columns == sort columns

    這樣小表的數(shù)據(jù)可以每次只讀取一部分,然后還是用大表一行一行的去匹配,這樣的join 沒有限制內(nèi)存的大小. 并且也可以執(zhí)行全外連接.

     

    Skew Join

    真實數(shù)據(jù)中數(shù)據(jù)傾斜是一定的, hadoop 中默認是使用

    hive.exec.reducers.bytes.per.reducer = 1000000000

    也就是每個節(jié)點的reduce 默認是處理1G大小的數(shù)據(jù),如果你的join 操作也產(chǎn)生了數(shù)據(jù)傾斜,那么你可以在hive 中設定

    set hive.optimize.skewjoin = true; 
    set hive.skewjoin.key = skew_key_threshold (default = 100000)

    hive 在運行的時候沒有辦法判斷哪個key 會產(chǎn)生多大的傾斜,所以使用這個參數(shù)控制傾斜的閾值,如果超過這個值,新的值會發(fā)送給那些還沒有達到的reduce, 一般可以設置成你

    (處理的總記錄數(shù)/reduce個數(shù))的2-4倍都可以接受.

    傾斜是經(jīng)常會存在的,一般select 的層數(shù)超過2層,翻譯成執(zhí)行計劃多于3個以上的mapreduce job 都很容易產(chǎn)生傾斜,建議每次運行比較復雜的sql 之前都可以設一下這個參數(shù). 如果你不知道設置多少,可以就按官方默認的1個reduce 只處理1G 的算法,那么  skew_key_threshold  = 1G/平均行長. 或者默認直接設成250000000 (差不多算平均行長4個字節(jié))

     

    Left Semi Join

    hive 中沒有in/exist 這樣的子句,所以需要將這種類型的子句轉成left semi join. left semi join 是只傳遞表的join key給map 階段 , 如果key 足夠小還是執(zhí)行map join, 如果不是則還是common join.

     

  • join 策略中的難點

    大多數(shù)只適合等值連接(equal join) ,

    范圍比較和全外連接沒有合適的支持

    提前分區(qū),零時分區(qū),排序,多種不同執(zhí)行計劃很難評價最優(yōu)方案.

    沒有考慮IO 比如臨時表,網(wǎng)絡消耗和網(wǎng)絡延遲時間,CPU時間,

    最優(yōu)的方案不代表系統(tǒng)資源消耗最少.

到此,關于“Hadoop中的兩表是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI