天天看點

total number of created files now is 100385, which exceeds 100000. Killing the j

今天将臨時表裡面的資料按照天分區插入到線上的表中去,出現了Hive建立的檔案數大于100000個的情況,我的SQL如下:

hive> insert overwrite table test partition(dt)
    > select * from table_tmp;
           

 table_tmp表裡面一共有570多G的資料,一共可以分成76個分區,SQL運作的時候建立了2163個Mapper,0個Reducers。程式運作到一般左右的時候出現了以下的異常:

[Fatal Error] total number of created files now is 100385, which exceeds 100000. Killing the job.
           

并最終導緻了SQL的運作失敗。這個錯誤的原因是因為Hive對建立檔案的總數有限制(

hive.exec.max.created.files

),預設是100000個,而這個SQL在運作的時候每個Map都會建立76個檔案,對應了每個分區,是以這個SQL總共會建立2163 * 76 = 164388個檔案,運作中肯定會出現上述的異常。為了能夠成功地運作上述的SQL,最簡單的方法就是加大

hive.exec.max.created.files

參數的設定。但是這有個問題,這會導緻在hadoop中産生大量的小檔案,因為table_tmp表的資料就570多G,那麼平均每個檔案的大小=570多G / 164388 = 3.550624133148405MB,可想而知,十萬多個這麼小的小檔案對Hadoop來說是多麼不好。那麼有沒有好的辦法呢?有!

  我們可以将dt相同的資料放到同一個Reduce處理,這樣最多也就産生76個檔案,将dt相同的資料放到同一個Reduce可以使用

DISTRIBUTE BY dt

實作,是以修改之後的SQL如下:

hive> insert overwrite table test partition(dt)
    > select * from table_tmp
    > DISTRIBUTE BY dt;
           

 修改完之後的SQL運作良好,并沒有出現上面的異常資訊,但是這裡也有個問題,因為這76個分區的資料分布很不均勻,有些Reduce的資料有30多G,而有些Reduce隻有幾K,直接導緻了這個SQL運作的速度很慢!

  能不能将570G的資料均勻的配置設定給Reduce呢?可以!我們可以使用

DISTRIBUTE BY rand()

将資料随機配置設定給Reduce,這樣可以使得每個Reduce處理的資料大體一緻。我設定每個Reduce處理5G的資料,對于570G的資料總共會起110左右的Reduces,修改的SQL如下:

hive> set hive.exec.reducers.bytes.per.reducer=5120000000;
hive> insert overwrite table test partition(dt)
    > select * from iteblog_tmp
    > DISTRIBUTE BY rand();
           

 這個SQL運作的時間很不錯,而且生産的檔案數量為Reduce的個數*分區的個數,不到1W個檔案。

繼續閱讀