本文为您介绍MaxCompute表的生命周期、避免全表扫描、小文件以及Hash Clustering表等高级功能。
生命周期
MaxCompute为表和分区提供数据生命周期管理功能。表(分区)数据从最后一次更新时间算起,在指定的时间段(即生命周期)内如果没有变动,则此表(分区)将被MaxCompute自动回收。生命周期只能以表为单位进行设置。
--创建表test_lifecycle,指定其生命周期为100天。
create table test_lifecycle(key string) lifecycle 100;
--修改表test_lifecycle的生命周期为50天。
alter table test_lifecycle set lifecycle 50;
MaxCompute会判断每张表(分区)中的LastModifiedTime距离当前时间的时长是否超过Lifecycle的值,如果超过则进行回收操作。
MaxCompute SQL提供TOUCH操作,将表或分区的LastModifiedTime值修改为当前时间。如果您使用TOUCH操作,MaxCompute会认为表或分区的数据有变动,生命周期的计算会重新开始,举例如下。
ALTER TABLE table_name TOUCH PARTITION(partition_col='partition_col_value', ...);
合理规划表的生命周期,在创建表时设置生命周期,可以有效减少存储压力。
对表数据的任何变动都会影响生命周期回收数据的时间判断,包括小文件合并。
避免全表扫描
在表设计时避免全表扫描。表设计是指建立分区表或者对扫描条件进行列设计,需要注意以下几点:
对数据表进行合理的分区。
把常用查询条件设置成列名。
对常用查询条件进行Hash Clustering。
在数据计算时避免全表扫描。
您可以增加分区过滤的条件或减少扫描的分区数,实现减少数据扫描量。
把全局扫描表的中间结果进行存储,形成中间表。
如果每天都需扫描某表一整年的分区,则计算消耗是非常大的。因此,建议您拆出一张中间表,每天做一次汇总,然后再扫描此中间表的一整年分区,从而减少扫描的数据量。
避免小文件
您可以参考如下建议避免产生小文件:
Reduce计算过程产生的小文件:只需要Insert Overwrite源表(或分区)即可,或者写入到新表中再删除源表。
Tunnel数据采集过程中产生小文件建议:
调用Tunnel SDK时,每当缓存达到64MB时,进行一次提交。
使用客户端时应避免频繁上传小文件,建议积累至一定的数量后再一次性上传。
如果导入的是分区表,建议给分区表设置生命周期,过期不用的数据将会被自动清理。
使用Insert Overwrite语句对源表(或分区)进行操作。
使用ALTER合并模式时,通过客户端命令进行合并。
建议为临时表设置生命周期,在到期后垃圾回收机制会自动回收临时表。
申请过多的DataHub Shard将会产生小文件问题,以下是申请DataHub Shard数目时的策略:
单个Shard的默认吞吐量是1MB/s,可以按照此数据分配实际的Shard数目(您也可以在此基础上多加几个)。
MaxCompute的每个Shard会有一个单独的Task,每隔5分钟或每满64MB,此Task会Commit一次,以提高在MaxCompute上查询数据的速度。当按照小时划分分区时,一个Shard每个小时将会产生12个文件。若此时数据量很少而Shard很多,则MaxCompute里就会出现很多小文件。
应按需分配Shard,避免过度分配。
转化Hash Clustering表
Hash Clustering表的优势在于可以实现Bucket Pruning优化、Aggregation优化以及存储优化。在创建表时,使用Clustered By指定Hash Key后,MaxCompute将对指定列进行Hash运算,按照Hash值分散到各个Bucket里。Hash Key值请选择重复键值少的列。
转化为Hash Clustering表的方法如下。
ALTER TABLE table_name [CLUSTERED BY (col_name [, col_name, ...]) [SORTED BY (col_name [ASC | DESC] [, col_name [ASC | DESC] ...])] INTO number_of_buckets BUCKETS]
Alter Table语句适用于存量表,在增加了新的聚集属性之后,新的分区将进行Hash Clustering存储。
创建完Hash Clustering表后,您可以使用Insert Overwrite语句将源表转化为Hash Clustering表。
Hash Clustering表存在以下限制:
不支持Insert Into语句,只能通过Insert Overwrite来添加数据。
由于Tunnel方式上传的数据是无序的,因此不支持直接使用Tunnel上传数据到Range Cluster表。