I've been reading this aws blog article,直到我谈到分区为止,这对我来说都是有意义的。用于创建表的查询如下所示:
, then the code is executable. This is a problem because it doesn't recognize the
这让我感到困惑的是,它的意思是“按年份划分(除其他事项外)”,但是在“ SQL”中没有其他地方指定年份中的数据部分。同样,这些列名称都没有日期类型。那么当您不告诉雅典娜数据的哪一部分是年,月或日时,雅典娜如何知道如何对这些数据进行分区?
在博客文章的上下文中,它说年份来自文件名,但没有任何步骤告诉Athena该信息。文章说这是预定义的格式:https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-log-entry-format,但是我看不到年份列。
编辑:这篇文章不是很明确,但是我认为这可能是说每个CREATE EXTERNAL TABLE IF NOT EXISTS elb_logs_raw_native_part (
request_timestamp string,
elb_name string,
request_ip string,
request_port int,
backend_ip string,
backend_port int,
request_processing_time double,
backend_processing_time double,
client_response_time double,
elb_response_code string,
backend_response_code string,
received_bytes bigint,
sent_bytes bigint,
request_verb string,
url string,
protocol string,
user_agent string,
ssl_cipher string,
ssl_protocol string )
PARTITIONED BY(year string, month string, day string) -- Where does Athena get this data?
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1','input.regex' = '([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:\-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \\\"([^ ]*) ([^ ]*) (- |[^ ]*)\\\" (\"[^\"]*\") ([A-Z0-9-]+) ([A-Za-z0-9.-]*)$' )
LOCATION 's3://athena-examples/elb/raw/';
列都是s3存储桶中的子目录?换句话说,PARTITIONED BY
子句中的第一个元素(在本例中为PARTITION BY
)是存储桶的第一个子目录,依此类推。
这对我来说仅是部分意义,因为同一篇文章说:“您可以跨多个维度(例如,月,周,日,小时或客户ID)或所有这些维度对数据进行分区。”我不明白,如果它们来自子目录,那么您将如何做所有这些工作,除非您的存储桶中有大量重复项。
答案 0 :(得分:1)
This article比原始版本解释得更好。
要创建带有分区的表,必须在CREATE TABLE语句中对其进行定义。使用PARTITIONED BY定义用于对数据进行分区的键。以下各节讨论了两种方案:
数据已经分区,存储在Amazon S3上,您需要在Athena上访问数据。
数据未分区。
我的问题是关于第一。为此,它说
分区存储在Amazon S3中的单独文件夹中。例如, 以下是部分广告展示次数列表:
aws s3 ls s3:// elasticmapreduce / samples / hive-ads / tables / impressions /
PRE dt=2009-04-12-13-00/ PRE dt=2009-04-12-13-05/ PRE dt=2009-04-12-13-10/ PRE dt=2009-04-12-13-15/ PRE dt=2009-04-12-13-20/ PRE dt=2009-04-12-14-00/ PRE dt=2009-04-12-14-05/ PRE dt=2009-04-12-14-10/ PRE dt=2009-04-12-14-15/ PRE dt=2009-04-12-14-20/ PRE dt=2009-04-12-15-00/ PRE dt=2009-04-12-15-05/
此处,日志以列名(dt)设置为等于日期,小时和分钟的增量进行存储。当你 为DDL提供父文件夹,架构和 分区列的名称,Athena可以查询其中的数据 子文件夹。
文章(IMO)的失败之处在于,它从未显示过aws s3 ls
。如果可以的话,我不会感到困惑。在本文中,假定有一个称为年,月和日的S3密钥。 PARTITION BY
指的是那些键。
如果文件的组织方式不那么整齐,则可以使用其他sql语句读取文件并对其进行分区(上面提到的方案2):
ALTER TABLE elb_logs_raw_native_part ADD PARTITION (year='2015',month='01',day='01') location 's3://athena-examples/elb/plaintext/2015/01/01/'
答案 1 :(得分:1)
非常有趣的发现丹尼尔!它使我想起了与AWS支持人员就此主题进行的旧讨论。我想在这里发布摘录,也许有人觉得它有用:
我刚刚阅读了有关在S3 [1]中对数据进行分区的Athena文档。
我想知道“场景1:数据已经以蜂巢格式分区并存储在S3上”,“存储分区数据”中给出的示例:
命令“ aws s3 ls s3:// elasticmapreduce / samples / hive-ads / tables / impressions /”返回例如“ PRE dt = 2009-04-12-13-00 /”。我的假设是正确的,为了能够在Athena中自动分区数据,我必须在S3文件夹名称前添加“ partition_key = actual_folder_name”?
否则我不明白为什么上面的示例ls命令返回以“ dt =“前缀开头的S3键。 我认为,此时应在Athena文档中更好地记录“ hive格式的S3上的数据”的含义。 [...]参考文献:
[1] https://docs.aws.amazon.com/athena/latest/ug/partitions.html
我了解您根据AWS文档https://docs.aws.amazon.com/athena/latest/ug/partitions.html
对Athena中的分区存在一些疑问回答您的问题:我的假设是正确的,为了能够在Athena中自动分区数据,我必须在S3文件夹名称前加上“ partition_key = actual_folder_name”?
是的,您是正确的,为了由Athena自动检测分区,S3前缀应该在'key = value'对中。否则,您必须使用上述文档本身中提到的“更改表..添加分区”命令来手动添加所有这些分区。
我知道您发现我们的文档在Hive样式分区方面不那么冗长。 [...]但是,关于Hive分区的描述较少的原因是由于Hive是一种开放源代码工具,有可用的开源文档详细解释了Hive样式分区。例如链接[1],等等。
如果由于手动性质而发现更改S3命名或手动添加分区是一项繁琐的任务,那么我建议您使用AWS Glue crawler [2]在您的S3数据上创建Athena表。即使在非Hive样式分区中,Glue也会检测到分区,并将“ Keys”分配给分区,例如“ partition_0”,“ partition_1”等。[...]
参考文献:
[1] http://hadooptutorial.info/partitioning-in-hive/
[2] https://docs.aws.amazon.com/glue/latest/dg/add-crawler.html