1. 程式人生 > >MaxCompute小檔案問題優化方案

MaxCompute小檔案問題優化方案

小檔案背景知識

小檔案定義

分散式檔案系統按塊Block存放,檔案大小比塊大小小的檔案(預設塊大小為64M),叫做小檔案。

如何判斷存在小檔案數量多的問題

檢視檔案數量

desc extended + 表名

image

判斷小檔案數量多的標準

1、非分割槽表,表文件數達到1000個,檔案平均大小小於64M
2、分割槽表: a) 單個分割槽檔案數達到1000個,檔案平均大小小於64M,
               b) 整個非分割槽表分割槽數達到五萬 (系統限制為6萬)

產生小檔案數量多的主要原因

1、表設計不合理導致:分割槽多導致檔案多,比如按天按小時按業務單元(假如有6個業務單元BU)分割槽,那麼一年下來,分割槽數將會達到36524

6=52560。
2、在使用Tunnel、Datahub、Console等資料整合工具上傳上傳資料時,頻繁Commit,寫入表(表分割槽)使用不合理導致:每個分割槽存在多個檔案,檔案數達到幾百上千,其中大多數是大小隻有幾 k 的小檔案。
3、在使用insert into寫入資料時過,幾條資料就寫入一次,並且頻繁的寫入。
4、Reduce過程中產生小檔案過多。
5、Job執行過程中生成的各種臨時檔案、回收站保留的過期的檔案過多。

注意:雖然在MaxCompute系統側會自動做小檔案合併的優化,但對於原因1、2、3需要客戶採用合理的表分割槽設計和上傳資料的方法才可以避免。

小檔案數量過多產生的影響

MaxCompute處理單個大檔案比處理多個小檔案更有效率,小檔案過多會影響整體的執行效能;小檔案過多會給檔案系統帶來一定的壓力,且影響空間的有效利用。MaxCompute對單個fuxi Instance可以處理的小檔案數限制為120個,檔案數過多影響fuxi instance數目,影響整體效能。

合併小檔案命令

set odps.merge.max.filenumber.per.job=50000; --值預設為50000個;當分割槽數大於50000時需要調整,最大可到1000000萬,大於1000000的提交多次merge
ALTER TABLE 表名[partition] MERGE SMALLFILES;

如何合併小檔案

分割槽表:

如果您的表已經是分割槽表,請檢查您的分割槽欄位是否是可收斂的,如果分割槽數過多同樣會影響計算效能,建議用日期做分割槽。
1、定期執行合併小檔案命令;
2、如果是按日期建的分割槽,可以每天對前一天的分割槽資料用insert overwrite重新覆蓋寫入。
例如:

insert overwrite table tableA partition (ds='20181220')
select * from tableA where ds='20181220';

非分割槽表:

如果您的表是非分割槽表,您可以定期執行合併小檔案命令來優化小檔案問題,但強烈建議您設計成分割槽表:
1、先建立一個新的分割槽表,建議按日期做分割槽,合理設定生命週期,以方便進行歷史資料回收;
2、把原非分割槽表的資料匯入新的分割槽表;(建議先暫停原非分割槽表的實時寫入業務)
例如:

create table sale_detail_patition like sale_detail;
alter table sale_detail_insert add partition(sale_date='201812120', region='china');
insert overwrite table sale_detail_patition partition (sale_date='20181220', region='china')
select * from sale_detail;

3、修改上下游業務:入庫程式改成寫入新分割槽表,查詢作業改成從新分割槽表中查詢;
4、新分割槽表完成資料遷移和驗證後,刪除原分割槽表。

注意:如果您使用insert overwrite重新寫入全量資料合併小檔案時,請注意一定不要同時存在insert overwrite和insert into同時存在的情況,否則有丟失資料的風險。

如何避免產生小檔案

優化表設計

合理設計表分割槽,分割槽欄位是儘量是可收斂或可管理的,如果分割槽數過多同樣會影響計算效能,建議用日期做分割槽,併合理設定表的生命週期,以方便對歷史資料回收,也可控制您的儲存成本。
參考文章:《MaxCompute 表(Table)設計規範》《MaxCompute表設計最佳實踐》

避免使用各種資料整合工具產生小檔案

1、Tunnel->MaxCompute
使用Tunnel上傳資料時避免頻繁commit,儘量保證每次提交的DataSize大於64M,請參考《離線批量資料通道Tunnel的最佳實踐及常見問題》

2、Datahub->MaxCompute
如果用Datahub產生小檔案,建議合理申請shard,可以根據topic的Throughput合理做shard合併,減少shard數量。可以根據topic的Throughput觀察資料流量變化,適當調大資料寫入的間隔時間。

申請Datahub shard數目的策略(申請過多的datahub shard將會產生小檔案問題)
1)預設吞吐量單個shard是1MB/s,可以按照這個分配實際的shard數目(可以在此基礎上多加幾個);
2)同步MaxCompute的邏輯是每個shard有一個單獨的task(滿足5分鐘或者64MB會commit一次),預設設定5分鐘是為了儘快能在MaxCompute查到資料。如果是按照小時建partition,那個一個shard每個小時有12個檔案。如果這個時候資料量很少,但是shard很多,在MaxCompute裡面就會很多小檔案(shard*12/hour)。所以不要過多的分配shard,按需分配。

參考建議:​​如果流量是5M/s,那麼就申請5個shard,為預防流量峰值預留20%的Buffer,可以申請6個shard。

3、DataX->MaxCompute
因為datax也是封裝了tunnel的SDK來寫入MaxCompute的,因此,建議您在配置ODPSWriter的時候,把blockSizeInMB這個引數不要設定太小,最好是64M以上。