一. Hive的創(chuàng)建文件數(shù)的限制
Hive對文件創(chuàng)建的總數(shù)是有限制的苍柏,這個限制取決于參數(shù):
hive.exec.max.created.files彻况,默認值是10000白胀。如果現(xiàn)在你的表有60個分區(qū)箱沦,然后你總共有2000個map,在運行的時候惕橙,每一個mapper都會創(chuàng)建60個文件瞧甩,對應(yīng)著每一個分區(qū),所以60*2000> 120000弥鹦,就會報錯:exceeds 100000.Killing the job
解決辦法:
最簡單的解決辦法就是調(diào)大hive.exec.max.created.files
參數(shù)肚逸。
但是如果說數(shù)據(jù)文件只有400G,那么你調(diào)整這個參數(shù)比如說40000
平均下來也就差不多每一個文件10.24MB,這樣的話就有40000多個小文件彬坏,我們知道小文件對于hadoop來講朦促,不是一件很好的事情。
這里就涉及到Hive當(dāng)中小文件的問題:
Hive之中小文件問題
我們知道小文件的對于Hadoop來講苍鲜,在小文件很多的時候思灰,可以把NameNode搞掛掉玷犹。
Hive里面什么時候會產(chǎn)生大量小文件呢?
- 一個大文件使用動態(tài)分區(qū)混滔,可能導(dǎo)致大量分區(qū)產(chǎn)生,從而產(chǎn)生多很多小文件歹颓,也會導(dǎo)致很多的mapper
- Reduce個數(shù)越多坯屿,小文件越多,Reduce個數(shù)和輸出文件是一樣的
- 數(shù)據(jù)源本身就包含很多的小文件
小文件會帶來什么影響呢巍扛?
文件的數(shù)量和大小會決定mapper任務(wù)的數(shù)量领跛,所以小文件越多,mapper任務(wù)越多撤奸,每一個mapper都會啟動一個JVM來運行吠昭,所以這些任務(wù)的初始化和執(zhí)行會花費大量的資源,嚴重影響性能
在NameNode每一個小文件的大約占150字節(jié)胧瓜,小文件太多矢棚,會嚴重影響NameNode
如何解決小文件的問題
如果動態(tài)分區(qū)不可預(yù)知的情況下,最好別用府喳,如果用也最好distributedby 分區(qū)字段蒲肋,這樣我們知道會對字段進行一個hash操作,這樣就會把相同的相同的分區(qū)給同一個Reduce去處理
如果Reduce數(shù)量太多,則減少reduce的數(shù)量
進行一些參數(shù)設(shè)置
設(shè)置 mapper輸入文件合并一些參數(shù):
set mapred.max.split.size=256000000; #每個Map最大輸入大小
set mapred.min.split.size.per.node=100000000; #一個節(jié)點上split的至少的大小(這個值決定了多個DataNode上的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000; #一個交換機下split的至少的大小(這個值決定了該機架下的文件是否需要合并)
set hive.input.format=org.apache.Hadoop.hive.ql.io.CombineHiveInputFormat; # 執(zhí)行Map前進行小文件合并
在開啟了org.apache.hadoop.hive.ql.io.CombineHiveInputFormat后兜粘,一個data node節(jié)點上多個小文件會進行合并申窘,合并文件數(shù)由mapred.max.split.size限制的大小決定。
mapred.min.split.size.per.node決定了多個data node上的文件是否需要合并~
mapred.min.split.size.per.rack決定了多個交換機上的文件是否需要合并~
設(shè)置 map輸出和reduce輸出進行合并的相關(guān)參數(shù)
hive.merge.mapfiles= true #設(shè)置 map輸出和reduce輸出進行合并的相關(guān)參數(shù)
hive.merge.mapredfiles= true 設(shè)置reduce端輸出進行合并孔轴,默認為false
hive.merge.size.per.task= 256 *1000 * 1000 設(shè)置合并文件的大小
hive.merge.smallfiles.avgsize=16000000 輸出文件的平均大小小于該值時剃法,啟動一個獨立的MapReduce任務(wù)進行文件merge