徹底解決Hive小文件問(wèn)題

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

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

圖片

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

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

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

圖片

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

因?yàn)檫@個(gè)表每天是有增量數(shù)據(jù)進(jìn)去的,增量數(shù)據(jù)會(huì)單獨(dú)生成一個(gè)文件,因?yàn)樵隽繑?shù)據(jù)本身不大,日積月累就形成了大量小文件。不僅對(duì)namenode的內(nèi)存造成壓力,對(duì)map端的小文件合并也有很大壓力。

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

  • 動(dòng)態(tài)分區(qū)插入數(shù)據(jù)的時(shí)候,會(huì)產(chǎn)生大量的小文件;
  • 數(shù)據(jù)源本身就包含有大量的小文件;
  • 做增量導(dǎo)入,比如Sqoop數(shù)據(jù)導(dǎo)入,一些增量insert等;
  • 分桶表,分桶表通常也會(huì)遇到小文件,本質(zhì)上還是增量導(dǎo)入的問(wèn)題;
  • 可以修改的表,這種Hive表是可以進(jìn)行修改的,通過(guò)配置stored as orc TBLPROPERTIES ("transactional"="true"),這種表最坑,每天都會(huì)有一個(gè)快照,到后面10G大小的數(shù)據(jù),表文件體積可以達(dá)到600G,時(shí)間越長(zhǎng)越大;

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

小文件的危害

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

小文件的解決方案

徹底解決小文件,分為了兩個(gè)方向,一個(gè)是小文件的預(yù)防,一個(gè)是大量小文件問(wèn)題已經(jīng)出現(xiàn)了,我們?cè)撛趺唇鉀Q。

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

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

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

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

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

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

2. 小文件的解決

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

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近發(fā)現(xiàn)離線任務(wù)對(duì)一個(gè)增量Hive表查詢?cè)絹?lái)越慢,推測(cè)是由小文件產(chǎn)生的 取HDFS查看確實(shí)存在480個(gè)小文件 于是...
    大空翼123閱讀 1,322評(píng)論 0 0
  • 問(wèn)題描述: 前些時(shí)間,運(yùn)維的同事反應(yīng)小文件過(guò)多問(wèn)題,需要我們?nèi)ヌ幚?,所以想到是以何種手段去合并現(xiàn)有的小文件。我們知...
    bigdata三十五畫生閱讀 1,314評(píng)論 0 0
  • 背景 前些時(shí)間,運(yùn)維的同事反應(yīng)小文件過(guò)多問(wèn)題,需要我們?nèi)ヌ幚?,所以想到是以何種手段去合并現(xiàn)有的小文件。我們知道Ha...
    香山上的麻雀閱讀 4,054評(píng)論 0 1
  • hive 中的小文件確定是向 hive 表中導(dǎo)入數(shù)據(jù)時(shí)產(chǎn)生。小文件過(guò)多產(chǎn)生的影響 首先對(duì)底層存儲(chǔ)HDFS來(lái)講,HD...
    Sql強(qiáng)閱讀 538評(píng)論 0 0
  • 今天仍然處于感冒狀態(tài),打開(kāi)電腦隨便寫一篇,然后滾回床上休息。 我們都知道,在HDFS中不宜存儲(chǔ)大量的小文件。所謂小...
    LittleMagic閱讀 9,612評(píng)論 12 17

友情鏈接更多精彩內(nèi)容