如何理解MaxCompute小文件问题的优化方案

16次阅读
没有评论

这篇文章给大家介绍如何理解 MaxCompute 小文件问题的优化方案,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

小文件定义

分布式文件系统按块 Block 存放,文件大小比块大小小的文件(默认块大小为 64M),叫做小文件。

如何判断存在小文件数量多的问题

查看文件数量

desc extended +  表名 

判断小文件数量多的标准

1、非分区表,表文件数达到 1000 个,文件平均大小小于 64M
2、分区表: a) 单个分区文件数达到 1000 个,文件平均大小小于 64M,
               b) 整个非分区表分区数达到五万(系统限制为 6 万)

产生小文件数量多的主要原因

1、表设计不合理导致:分区多导致文件多,比如按天按小时按业务单元(假如有 6 个业务单元 BU)分区,那么一年下来,分区数将会达到 365246=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 同时存在的情况,否则有丢失数据的风险。

如何避免产生小文件优化表设计

合理设计表分区,分区字段是尽量是可收敛或可管理的,如果分区数过多同样会影响计算性能,建议用日期做分区,并合理设置表的生命周期,以方便对历史数据回收,也可控制您的存储成本。

避免使用各种数据集成工具产生小文件

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 以上。

关于如何理解 MaxCompute 小文件问题的优化方案就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。