1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        徹底解決Hive小文件問題

        共 2816字,需瀏覽 6分鐘

         ·

        2021-09-23 15:39

        最近發(fā)現(xiàn)離線任務(wù)對一個增量Hive表的查詢越來越慢,這引起了我的注意,我在cmd窗口手動執(zhí)行count操作查詢發(fā)現(xiàn),速度確實很慢,才不到五千萬的數(shù)據(jù),居然需要300s,這顯然是有問題的,我推測可能是有小文件。

        我去hdfs目錄查看了一下該目錄:

        發(fā)現(xiàn)確實有很多小文件,有480個小文件,我覺得我找到了問題所在,那么合并一下小文件吧:

        insert into test select * from table distribute by floor (rand()*5);

        這里使用distribute by進行了一個小文件的合并,通過rand() * 5,保證了從map端輸出的數(shù)據(jù),最多到5個reducer,將小文件數(shù)量控制了下來,現(xiàn)在只有3個文件了。

        合并小文件后,再次做同樣的查詢,15s就完成了。確實忽略了,增量數(shù)據(jù)會導(dǎo)致小文件,應(yīng)該在當(dāng)初做的時候就做定時的小文件合并,而不是等到現(xiàn)在才發(fā)現(xiàn)。

        因為這個表每天是有增量數(shù)據(jù)進去的,增量數(shù)據(jù)會單獨生成一個文件,因為增量數(shù)據(jù)本身不大,日積月累就形成了大量小文件。不僅對namenode的內(nèi)存造成壓力,對map端的小文件合并也有很大壓力。

        小文件產(chǎn)生的原因

        • 動態(tài)分區(qū)插入數(shù)據(jù)的時候,會產(chǎn)生大量的小文件;

        • 數(shù)據(jù)源本身就包含有大量的小文件;

        • 做增量導(dǎo)入,比如Sqoop數(shù)據(jù)導(dǎo)入,一些增量insert等;

        • 分桶表,分桶表通常也會遇到小文件,本質(zhì)上還是增量導(dǎo)入的問題;

        • 可以修改的表,這種Hive表是可以進行修改的,通過配置stored as orc TBLPROPERTIES ("transactional"="true"),這種表最坑,每天都會有一個快照,到后面10G大小的數(shù)據(jù),表文件體積可以達到600G,時間越長越大;

        小文件的問題有很多,實際中各種原因,由于自己的不小心,前期沒有做好預(yù)防都會產(chǎn)生大量小文件,讓線上的離線任務(wù)神不知鬼不覺,越跑越慢。

        小文件的危害

        1. 給namenode內(nèi)存中fsImage的合并造成壓力,如果namenode內(nèi)存使用完了,這個集群將不能再存儲文件了;
        2. 雖然map階段都設(shè)置了小文件合并,org.apache.hadoop.hive.ql.io.CombineHiveInputFormat,太多小文件導(dǎo)致合并時間較長,查詢緩慢;

        小文件的解決方案

        徹底解決小文件,分為了兩個方向,一個是小文件的預(yù)防,一個是大量小文件問題已經(jīng)出現(xiàn)了,我們該怎么解決。

        1. 小文件的預(yù)防

        網(wǎng)上有些解決方案,是調(diào)節(jié)參數(shù),這些參數(shù)在我使用的Hive2是默認都開啟了的:

        //每個Map最大輸入大小(這個值決定了合并后文件的數(shù)量)
        set mapred.max.split.size=256000000;  
        //一個節(jié)點上split的至少的大小(這個值決定了多個DataNode上的文件是否需要合并)
        set mapred.min.split.size.per.node=100000000;
        //一個交換機下split的至少的大小(這個值決定了多個交換機上的文件是否需要合并)  
        set mapred.min.split.size.per.rack=100000000;
        //執(zhí)行Map前進行小文件合并
        set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 
        //設(shè)置map端輸出進行合并,默認為true
        set hive.merge.mapfiles = true
        //設(shè)置reduce端輸出進行合并,默認為false
        set hive.merge.mapredfiles = true
        //設(shè)置合并文件的大小
        set hive.merge.size.per.task = 256*1000*1000
        //當(dāng)輸出文件的平均大小小于該值時,啟動一個獨立的MapReduce任務(wù)進行文件merge。
        set hive.merge.smallfiles.avgsize=16000000

        有些公司用的版本不同,低版本可能有些配置不一樣,最好檢查一下上面這些配置是否設(shè)置,然后根據(jù)自己的實際集群情況進行設(shè)置。

        小文件的預(yù)防,主要還是要根據(jù)小文件的產(chǎn)生原因,來進行預(yù)防。

        1. 動態(tài)分區(qū)插入的時候,保證有靜態(tài)分區(qū),不要誤判導(dǎo)致產(chǎn)生大量分區(qū),大量分區(qū)加起來,自然就有大量小文件;
        2. 如果源表是有大量小文件的,在導(dǎo)入數(shù)據(jù)到目標(biāo)表的時候,如果只是insert into dis select * from origin的話,目標(biāo)表通常也有很多小文件。如果有分區(qū),比如dt, hour,可以使用distribute by dt, hour,保證每個小時的數(shù)據(jù)在一個reduce里面;
        3. 類似sqoop增量導(dǎo)入,還有hive一些表的查詢增量導(dǎo)入,這些肯定是有小文件的,需要進行一周甚至一天定時任務(wù)的小文件合并。

        2. 小文件的解決

        上面是平時開發(fā)數(shù)據(jù)任務(wù)時候,小文件的預(yù)防,但如果由于我們的大意,小文件問題已經(jīng)產(chǎn)生了,就需要解決了。通常就是insert overwrite了。

        insert overwrite table test [partition(hour=...)] select * from test distribute by floor (rand()*5);

        注:這個語句把test表的數(shù)據(jù)查詢出來,overwrite覆蓋test表,不用擔(dān)心如果overwrite失敗,數(shù)據(jù)沒了,這里面是有事物性保證的,可以觀察一下執(zhí)行的時候,在test表hdfs文件目錄下面有個臨時文件夾。如果是分區(qū)表,加上partition,表示對該分區(qū)進行overwrite。

        如果是orc格式存儲的表,還可以使用alter table test [partition(...)] concatenate進行小文件的合并,不過這種方法僅僅適用于orc格式存儲的表。

        猜你喜歡

        Hadoop3數(shù)據(jù)容錯技術(shù)(糾刪碼)
        Hadoop 數(shù)據(jù)遷移用法詳解
        Flink實時計算topN熱榜
        數(shù)倉建模分層理論
        一文搞懂Hive的數(shù)據(jù)存儲與壓縮
        大數(shù)據(jù)組件重點學(xué)習(xí)這幾個


        瀏覽 55
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            蜜臀久久99精品久久久画质超高清 | 91久久婷婷 | 最近日韩中文字幕中文翻译歌词 | 国产在线观看不卡 | 黄色视频网站观看 | 伊人手机在线视频 | 黄A在线免费观看 | 成人无码AV片在线观看 | 欧美性爱免费观看 | 日韩在线一级片 |