为何未配置Athena却自动按日期路径生成partition_0等分区?
我使用以下CloudFormation配置读取由Kinesis Firehose写入S3的数据:
S3AthenaStore: Type: AWS::S3::Bucket Properties: BucketName: ${self:custom.s3AthenaStore} AnalysisGlueDatabase: Type: AWS::Glue::Database Properties: CatalogId: !Ref AWS::AccountId DatabaseInput: Name: !Join - '' - - '${self:custom.glueName}-' - 'db' Description: "Analysis aws Glue database" DependsOn: - S3AthenaStore AnalyticsGlueRole: Type: AWS::IAM::Role DependsOn: - S3AnalyticsStore Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "glue.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" ManagedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole'] Policies: - PolicyName: "S3BucketAccessPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "s3:GetObject" - "s3:PutObject" Resource: - !Join - '' - - !GetAtt S3AnalyticsStore.Arn - "*" AnalyticsGlueCrawler: Type: AWS::Glue::Crawler Properties: Name: "AnalysisCrawler" Role: !GetAtt AnalyticsGlueRole.Arn DatabaseName: !Ref AnalysisGlueDatabase Targets: S3Targets: - Path: !Ref S3AnalyticsStore SchemaChangePolicy: UpdateBehavior: "LOG" DeleteBehavior: "LOG" Schedule: ScheduleExpression: "cron(00 0/1 * * ? *)" RecrawlPolicy: RecrawlBehavior: CRAWL_NEW_FOLDERS_ONLY DependsOn: - AnalyticsGlueRole - AnalysisGlueDatabase AnalyticsAthenaWorkGroup: Type: AWS::Athena::WorkGroup Properties: Name: ${self:service}-${self:provider.stage}-wg WorkGroupConfiguration: ResultConfiguration: OutputLocation: !Join - '' - - 's3://' - !Ref S3AthenaStore DependsOn: - S3AthenaStore
S3中数据的文件夹路径格式为:${bucket}/${year}/${month}/${date}/${hour}/event-collection-stream-staging-deliver-1-2022-07-14-23-51-22-cdb2f06a-e825-47d0-a781-efd4195ab88d.gz,单条数据内容示例如下:
{"anonymous_id":"123","url":"-","event_type":"pageView","timestamp":"2022-07-12T03:29:47.186Z","source_ip":"69.113.177.222","user_agent":"curl/7.54.0"}
我的疑问是:为何数据在Athena中被自动分区?执行select * from page_view_store_staging时,返回结果除原有字段外,还多出partition_0至partition_3四个分区列,其中partition_0的值为2022这类年份值。我并未在配置中指定任何分区设置,这是怎么回事?
这是AWS Glue Crawler的自动分区检测机制导致的:
- 当Glue Crawler扫描到S3路径存在多层级目录结构时,会默认将这些目录层级识别为分区列,按顺序命名为
partition_0、partition_1、partition_2、partition_3... - 你的S3数据路径是
${bucket}/${year}/${month}/${date}/${hour}/,其中year、month、date、hour四个层级被Crawler自动识别为分区,因此生成了对应的四个分区列。 - 即使没有使用Hive标准的
key=value格式(比如year=2022/month=07/),Crawler依然会把目录层级当作分区处理,只是无法自动识别分区列的语义名称,只能用默认的partition_N命名。
根据你的需求,有几种处理方式:
修改S3输出路径为Hive风格分区格式
调整Kinesis Firehose的输出路径模板,使用key=value的格式,比如:${bucket}/year=!{timestamp:yyyy}/month=!{timestamp:MM}/date=!{timestamp:dd}/hour=!{timestamp:HH}/这样Glue Crawler会自动识别出
year、month、date、hour这些有语义的分区列名,而不是默认的partition_N。配置Glue Crawler的分区映射规则
在Glue Crawler的配置中添加分区映射规则,将默认的partition_0映射为year,partition_1映射为month,以此类推。具体操作是在Crawler的“配置”页面找到“分区映射”,添加对应规则即可。手动修改Glue表结构
直接在Glue控制台修改对应表的分区列名称,但需要注意:后续Crawler运行时,若SchemaChangePolicy设置为更新模式,可能会覆盖手动修改的内容,建议配合调整Crawler的SchemaChangePolicy为LOG或DEPRECATE_IN_DATABASE。
内容的提问来源于stack exchange,提问作者Igor Shmukler

