<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          數(shù)倉(cāng)面試高頻考點(diǎn)--解決hive小文件過(guò)多問(wèn)題

          共 4145字,需瀏覽 9分鐘

           ·

          2022-04-09 21:17

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

          hive 中的小文件肯定是向 hive 表中導(dǎo)入數(shù)據(jù)時(shí)產(chǎn)生,所以先看下向 hive 中導(dǎo)入數(shù)據(jù)的幾種方式

          1. 直接向表中插入數(shù)據(jù)

          insert?into?table?A?values?(1,'zhangsan',88),(2,'lisi',61);
          這種方式每次插入時(shí)都會(huì)產(chǎn)生一個(gè)文件,多次插入少量數(shù)據(jù)就會(huì)出現(xiàn)多個(gè)小文件,但是這種方式生產(chǎn)環(huán)境很少使用,可以說(shuō)基本沒(méi)有使用的
          1. 通過(guò)load方式加載數(shù)據(jù)

          load data local inpath '/export/score.csv' overwrite into table A  -- 導(dǎo)入文件
          load data local inpath '/export/score' overwrite into table A -- 導(dǎo)入文件夾
          使用 load 方式可以導(dǎo)入文件或文件夾,當(dāng)導(dǎo)入一個(gè)文件時(shí),hive表就有一個(gè)文件,當(dāng)導(dǎo)入文件夾時(shí),hive表的文件數(shù)量為文件夾下所有文件的數(shù)量
          1. 通過(guò)查詢方式加載數(shù)據(jù)

          insert?overwrite?table?A??select?s_id,c_name,s_score?from?B;
          這種方式是生產(chǎn)環(huán)境中常用的,也是最容易產(chǎn)生小文件的方式

          insert 導(dǎo)入數(shù)據(jù)時(shí)會(huì)啟動(dòng) MR 任務(wù),MR中 reduce 有多少個(gè)就輸出多少個(gè)文件

          所以, 文件數(shù)量=ReduceTask數(shù)量*分區(qū)數(shù)

          也有很多簡(jiǎn)單任務(wù)沒(méi)有reduce,只有map階段,則

          文件數(shù)量=MapTask數(shù)量*分區(qū)數(shù)

          每執(zhí)行一次 insert 時(shí)hive中至少產(chǎn)生一個(gè)文件,因?yàn)?insert 導(dǎo)入時(shí)至少會(huì)有一個(gè)MapTask。
          像有的業(yè)務(wù)需要每10分鐘就要把數(shù)據(jù)同步到 hive 中,這樣產(chǎn)生的文件就會(huì)很多。

          小文件過(guò)多產(chǎn)生的影響

          1. 首先對(duì)底層存儲(chǔ)HDFS來(lái)說(shuō),HDFS本身就不適合存儲(chǔ)大量小文件,小文件過(guò)多會(huì)導(dǎo)致namenode元數(shù)據(jù)特別大, 占用太多內(nèi)存,嚴(yán)重影響HDFS的性能

          2. 對(duì) hive 來(lái)說(shuō),在進(jìn)行查詢時(shí),每個(gè)小文件都會(huì)當(dāng)成一個(gè)塊,啟動(dòng)一個(gè)Map任務(wù)來(lái)完成,而一個(gè)Map任務(wù)啟動(dòng)和初始化的時(shí)間遠(yuǎn)遠(yuǎn)大于邏輯處理的時(shí)間,就會(huì)造成很大的資源浪費(fèi)。而且,同時(shí)可執(zhí)行的Map數(shù)量是受限的。

          怎么解決小文件過(guò)多

          1. 使用 hive 自帶的 concatenate 命令,自動(dòng)合并小文件

          使用方法:

          #對(duì)于非分區(qū)表alter table A concatenate;
          #對(duì)于分區(qū)表alter table B partition(day=20201224) concatenate;

          舉例:

          #向 A 表中插入數(shù)據(jù)hive (default)> insert into table A values (1,'aa',67),(2,'bb',87);hive (default)> insert into table A values (3,'cc',67),(4,'dd',87);hive (default)> insert into table A values (5,'ee',67),(6,'ff',87);
          #執(zhí)行以上三條語(yǔ)句,則A表下就會(huì)有三個(gè)小文件,在hive命令行執(zhí)行如下語(yǔ)句#查看A表下文件數(shù)量hive (default)> dfs -ls /user/hive/warehouse/A;Found 3 items-rwxr-xr-x 3 root supergroup 378 2020-12-24 14:46 /user/hive/warehouse/A/000000_0-rwxr-xr-x 3 root supergroup 378 2020-12-24 14:47 /user/hive/warehouse/A/000000_0_copy_1-rwxr-xr-x 3 root supergroup 378 2020-12-24 14:48 /user/hive/warehouse/A/000000_0_copy_2
          #可以看到有三個(gè)小文件,然后使用 concatenate 進(jìn)行合并hive (default)> alter table A concatenate;
          #再次查看A表下文件數(shù)量hive (default)> dfs -ls /user/hive/warehouse/A;Found 1 items-rwxr-xr-x 3 root supergroup 778 2020-12-24 14:59 /user/hive/warehouse/A/000000_0
          #已合并成一個(gè)文件

          注意:?
          1、concatenate 命令只支持 RCFILE 和 ORC 文件類型。?
          2、使用concatenate命令合并小文件時(shí)不能指定合并后的文件數(shù)量,但可以多次執(zhí)行該命令。?
          3、當(dāng)多次使用concatenate后文件數(shù)量不在變化,這個(gè)跟參數(shù) mapreduce.input.fileinputformat.split.minsize=256mb 的設(shè)置有關(guān),可設(shè)定每個(gè)文件的最小size。

          2. 調(diào)整參數(shù)減少M(fèi)ap數(shù)量

          • 設(shè)置map輸入合并小文件的相關(guān)參數(shù)

          #執(zhí)行Map前進(jìn)行小文件合并#CombineHiveInputFormat底層是 Hadoop的 CombineFileInputFormat 方法#此方法是在mapper中將多個(gè)文件合成一個(gè)split作為輸入set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 默認(rèn)
          #每個(gè)Map最大輸入大小(這個(gè)值決定了合并后文件的數(shù)量)set mapred.max.split.size=256000000; -- 256M
          #一個(gè)節(jié)點(diǎn)上split的至少的大小(這個(gè)值決定了多個(gè)DataNode上的文件是否需要合并)set mapred.min.split.size.per.node=100000000; -- 100M
          #一個(gè)交換機(jī)下split的至少的大小(這個(gè)值決定了多個(gè)交換機(jī)上的文件是否需要合并)set mapred.min.split.size.per.rack=100000000; -- 100M
          • 設(shè)置map輸出和reduce輸出進(jìn)行合并的相關(guān)參數(shù):

          #設(shè)置map端輸出進(jìn)行合并,默認(rèn)為trueset hive.merge.mapfiles = true;
          #設(shè)置reduce端輸出進(jìn)行合并,默認(rèn)為falseset hive.merge.mapredfiles = true;
          #設(shè)置合并文件的大小set hive.merge.size.per.task = 256*1000*1000; -- 256M
          #當(dāng)輸出文件的平均大小小于該值時(shí),啟動(dòng)一個(gè)獨(dú)立的MapReduce任務(wù)進(jìn)行文件mergeset hive.merge.smallfiles.avgsize=16000000; -- 16M
          • 啟用壓縮

          # hive的查詢結(jié)果輸出是否進(jìn)行壓縮set hive.exec.compress.output=true;
          # MapReduce Job的結(jié)果輸出是否使用壓縮set mapreduce.output.fileoutputformat.compress=true;

          3. 減少Reduce的數(shù)量

          #reduce 的個(gè)數(shù)決定了輸出的文件的個(gè)數(shù),所以可以調(diào)整reduce的個(gè)數(shù)控制hive表的文件數(shù)量,#hive中的分區(qū)函數(shù) distribute by 正好是控制MR中partition分區(qū)的,#然后通過(guò)設(shè)置reduce的數(shù)量,結(jié)合分區(qū)函數(shù)讓數(shù)據(jù)均衡的進(jìn)入每個(gè)reduce即可。
          #設(shè)置reduce的數(shù)量有兩種方式,第一種是直接設(shè)置reduce個(gè)數(shù)set mapreduce.job.reduces=10;
          #第二種是設(shè)置每個(gè)reduce的大小,Hive會(huì)根據(jù)數(shù)據(jù)總大小猜測(cè)確定一個(gè)reduce個(gè)數(shù)set hive.exec.reducers.bytes.per.reducer=5120000000; -- 默認(rèn)是1G,設(shè)置為5G
          #執(zhí)行以下語(yǔ)句,將數(shù)據(jù)均衡的分配到reduce中set mapreduce.job.reduces=10;insert overwrite table A partition(dt)select * from Bdistribute by rand();
          解釋:如設(shè)置reduce數(shù)量為10,則使用 rand(), 隨機(jī)生成一個(gè)數(shù) x % 10 ,這樣數(shù)據(jù)就會(huì)隨機(jī)進(jìn)入 reduce 中,防止出現(xiàn)有的文件過(guò)大或過(guò)小

          4. 使用hadoop的archive將小文件歸檔

          Hadoop Archive簡(jiǎn)稱HAR,是一個(gè)高效地將小文件放入HDFS塊中的文件存檔工具,它能夠?qū)⒍鄠€(gè)小文件打包成一個(gè)HAR文件,這樣在減少namenode內(nèi)存使用的同時(shí),仍然允許對(duì)文件進(jìn)行透明的訪問(wèn)

          #用來(lái)控制歸檔是否可用set hive.archive.enabled=true;#通知Hive在創(chuàng)建歸檔時(shí)是否可以設(shè)置父目錄set hive.archive.har.parentdir.settable=true;#控制需要?dú)w檔文件的大小set har.partfile.size=1099511627776;
          #使用以下命令進(jìn)行歸檔ALTER TABLE A ARCHIVE PARTITION(dt='2020-12-24', hr='12');
          #對(duì)已歸檔的分區(qū)恢復(fù)為原文件ALTER TABLE A UNARCHIVE PARTITION(dt='2020-12-24', hr='12');

          注意: ?
          歸檔的分區(qū)可以查看不能 insert overwrite,必須先 unarchive

          最后

          如果是新集群,沒(méi)有歷史遺留問(wèn)題的話,建議hive使用 orc 文件格式,以及啟用 lzo 壓縮。
          這樣小文件過(guò)多可以使用hive自帶命令 concatenate 快速合并。

          瀏覽 36
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  特色黄色片| 亚洲琪琪| 国产视频99在线观看 | 欧美性掹交xxx | 欧美亚洲中文 |