读取以分区方式存储的OSS数据

MaxCompute支持创建OSS外部表为分区表,访问OSS上以分区方式存储的数据,通过该方式可降低读取数据量并提升数据处理效率。本文为您介绍MaxCompute支持的OSS标准分区路径格式和自定义分区路径格式。

背景信息

创建OSS外部表后,MaxCompute会全量扫描OSS目录下的所有数据,包括子目录下的数据文件。但当数据量比较大时,对全目录扫描会产生不必要的I/O消耗以及数据处理时间。通常,解决该问题有如下两种方法:

  • (推荐)方式一:在OSS上将数据以标准分区路径或自定义分区路径方式存储。通过MaxCompute新建OSS外部表时,您需要在建表语句指定分区及oss_location信息。推荐您使用标准分区路径。更多分区路径信息,请参见标准分区路径格式自定义分区路径格式

  • 方式二:规划多个数据存放路径。创建多个OSS外部表来读取各个路径下的数据。即每个OSS外部表指向OSS数据的一个子集。该方式操作比较繁琐,数据管理效果不佳。不推荐使用该方式。

标准分区路径格式

标准分区路径格式如下。

oss://<oss_endpoint>/<Bucket名称>/<目录名称>/<partitionKey1=value1>/<partitionKey2=value2>/...
说明

因为OSS数据是离线准备的,即通过OSS控制台或其他OSS工具上传到OSS中,所以数据的路径格式取决于上传时的格式。

参数名称

可选/必填

说明

oss_endpoint

必填

OSS访问域名信息。建议您使用OSS提供的内网域名,否则将产生OSS流量费用。更多OSS内网域名信息,请参见访问域名和数据中心

说明

建议数据文件存放的OSS地域与MaxCompute项目所在地域保持一致。由于MaxCompute只在部分地域部署,跨地域的数据连通性可能存在问题。

Bucket名称

必填

OSS存储空间名称,即Bucket名称。查看存储空间名称操作,请参见列举存储空间

目录名称

必填

指定OSS目录名称。目录后不需要指定文件名。

partitionKey

必填

OSS外部表的分区列名。

value

必填

OSS外部表的分区列值。

例如,某公司会将每天产生的Log文件以CSV格式存放在OSS上,并通过MaxCompute以天为周期处理数据。则存储OSS数据的标准分区路径应设置如下。

oss://oss-odps-test/log_data/year=2016/month=06/day=01/logfile
oss://oss-odps-test/log_data/year=2016/month=06/day=02/logfile
oss://oss-odps-test/log_data/year=2016/month=07/day=10/logfile
oss://oss-odps-test/log_data/year=2016/month=08/day=08/logfile
...

基于上述分区存储路径,创建OSS外部表、引入并分析分区数据的命令示例如下。

--创建OSS外部表。
CREATE EXTERNAL TABLE log_table_external (
    click STRING,
    ip STRING,
    url STRING
  )
partitioned BY (
    year STRING,
    month STRING,
    day STRING
  )
stored BY 'com.aliyun.odps.CsvStorageHandler'
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket名称/oss-odps-test/log_data/';

--引入OSS分区数据。
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '01');
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '02');
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '07', day = '10');
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '08', day = '08');
...

--分析数据。只访问log_data/year=2016/month=06/day=01子目录下的文件(logfile),不会对整个log_data目录做全量数据扫描。
SELECT count(DISTINCT(ip)) FROM log_table_external WHERE year = '2016' AND month = '06' AND day = '01';

完整的读取标准分区路径数据示例,请参见示例:通过内置文本数据解析器创建OSS外部表-分区表

自定义分区路径格式

如果OSS上的数据实际上已按照分区方式存储,只是路径不是标准分区路径格式时,MaxCompute支持将不同的子目录绑定至不同的分区。

自定义分区路径格式示例如下,只有分区列值,无分区列名。

oss://oss-odps-test/log_data_customized/2016/06/01/logfile
oss://oss-odps-test/log_data_customized/2016/06/02/logfile
oss://oss-odps-test/log_data_customized/2016/07/10/logfile
oss://oss-odps-test/log_data_customized/2016/08/08/logfile
...

创建OSS外部表后,通过alter table ... add partition ... location ...命令指定子目录,将不同的子目录绑定到不同的分区,命令示例如下。

ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '01')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket名称/oss-odps-test/log_data_customized/2016/06/01/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '02')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket名称/oss-odps-test/log_data_customized/2016/06/02/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '07', day = '10')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket名称/oss-odps-test/log_data_customized/2016/07/10/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '08', day = '08')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket名称/oss-odps-test/log_data_customized/2016/08/08/';

基于该方式,自定义分区路径后,即使数据存放不符合推荐的标准分区路径格式,您也可以正确地对子目录数据进行访问。