Hive 解決Hive建立檔案數過多的問題

2021-08-05 23:51:34 字數 2121 閱讀 1877

工作中遇到的問題之一,這篇說得很清楚,轉過來收藏:

將臨時表裡面的資料按照天分割槽插入到線上的表中去,出現了hive

建立的檔案數大於100000個的情況,我的sql如下:

hive>insertoverwritetabletest partition(dt)

>select*fromiteblog_tmp;

[fatal error] total number of created files now is100385, which exceeds100000. killing the job.

並最終導致了sql的執行失敗。這個錯誤的原因是因為hive

對建立檔案的總數有限制(hive.exec.max.created.files),預設是100000個,而這個sql在執行的時候每個map都會建立76個檔案,對應了每個分割槽,所以這個sql總共會建立2163 * 76 = 164388個檔案,執行中肯定會出現上述的異常。為了能夠成功地執行上述的sql,最簡單的方法就是加大hive.exec.max.created.files引數的設定。但是這有個問題,這會導致在iteblog中產生大量的小檔案,因為iteblog_tmp表的資料就570多g,那麼平均每個檔案的大小=570多g / 164388 = 3.550624133148405mb,可想而知,十萬多個這麼小的小檔案對hadoop來說是多麼不好。那麼有沒有好的辦法呢?有!

我們可以將dt相同的資料放到同乙個reduce處理,這樣最多也就產生76個檔案,將dt相同的資料放到同乙個reduce可以使用distribute by dt實現,所以修改之後的sql如下:

hive>insertoverwritetabletest partition(dt)

>select*fromiteblog_tmp

> distributebydt;

修改完之後的sql執行良好,並沒有出現上面的異常資訊,但是這裡也有個問題,因為這76個分割槽的資料分布很不均勻,有些reduce的資料有30多g,而有些reduce只有幾k,直接導致了這個sql執行的速度很慢!

能不能將570g的資料均勻的分配給reduce呢?可以!我們可以使用distribute by rand()將資料隨機分配給reduce,這樣可以使得每個reduce處理的資料大體一致。我設定每個reduce處理5g的資料,對於570g的資料總共會起110左右的reduces,修改的sql如下:

hive>sethive.exec.reducers.bytes.per.reducer=5120000000;

hive>insertoverwritetabletest partition(dt)

>select*fromiteblog_tmp

> distributebyrand();

這個sql執行的時間很不錯,而且生產的檔案數量為reduce的個數*分割槽的個數,不到1w個檔案。

resource:

NIFI 檔案資料寫入hive

目的 nifi使用背景 希望借助nifi監控某個目錄,能夠將被監控目錄下的資料檔案採集並寫入hive中去。nifi提供了puthiveql puthivestreaming putsql三種processor,這三種processor對flowfile的要求也不盡相同。本文選用了如下圖1所示的幾種p...

hive創標 hive建立表

一 為什麼要建立分割槽表 1 select查詢中會掃瞄整個表內容,會消耗大量時間。由於相當多的時候人們只關心表中的一部分資料,故建表時引入了分割槽概念。2 hive分割槽表 是指在建立表時指定的partition的分割槽空間,若需要建立有分割槽的表,需要在create表的時候呼叫可選引數partit...

hive 建立索引

索引是hive0.7之後才有的功能,建立索引需要評估其合理性,因為建立索引也是要磁碟空間,維護起來也是需要代價的 create index idx user phone on table user phone with phone message user phone as org.apache.h...