AWS Glue 数据存储:将单个文件添加到分区
AWS Glue Datastore: Add individual files to partitions
我有一个按天分区的 s3 目录结构 s3://userlogs/year=YYYY/month=MM/day=DD/
我有服务器不断地用文件填充当天的目录——它们每天添加大约 6,000 个文件。添加每个文件后,我想更新 Glue 数据存储中的 table userlogs
以包含它。
问题是 AWS glue 只为我们提供了一种使用像
这样的命令将全新分区(及其相应目录)添加到 table 的方法
ALTER TABLE userlogs ADD
PARTITION (year = '2016', month = '01', day = '01) LOCATION 's3://userlogs/year=2016/month=01/day=02/'
但是,每次我 运行 我假设 Glue 需要扫描该目录中所有可能的数千个文件的命令。
我真正想要的是某种 method/command 可以执行以下操作:
ALTER TABLE userlogs UPDATE
PARTITION (year = '2016', month = '01', day = '01) ADD FILE's3://userlogs/year=2016/month=01/day=02/todays_file_no_3423.parquet.gz'
有没有什么方法可以实现这个目标而不涉及重构我的数据存储方式?
命令ALTER TABLE ...
不会扫描您在 S3 中的数据(因此它是免费的)。它只是定义有关您在 AWS Glue 数据目录中的数据的元信息,即应该可以使用 Athena 查询搜索的 S3 中文件的位置,因此,此命令完成所需的时间不到一秒。
因此,您不需要单独添加文件,只要您在 glue metastore 中有一个分区 "points" 到这些文件所在的 S3 位置。所以之后
ALTER TABLE userlogs ADD
PARTITION (year = '2016', month = '01', day = '01')
LOCATION 's3://userlogs/year=2016/month=01/day=01/';
您可以将任意数量的文件添加到 s3://userlogs/year=2016/month=01/day=01/
,它们的所有内容都可以通过 Athena 进行查询。
补充说明 TL;DR
不确定 ALTER TABLE userlogs ADD PARTITION ...
的以下行为是否符合预期,但是:
只检查S3 bucket是否存在,不检查S3全路径。所以下面的DDL语句会成功
ALTER TABLE userlogs ADD
PARTITION (..., day='01') LOCATION 's3://userlogs/year=2016/month=01/day=01/'
PARTITION (..., day='wrong') LOCATION 's3://userlogs/year=2016/month=01/day=wrong_path/';
正常查询也会成功,但结果不同,因为错误路径中没有文件
SELECT COUNT(*) FROM userlogs WHERE day = '01' -- outputs some value
SELECT COUNT(*) FROM userlogs WHERE day = 'wrong' -- outputs 0
它不会检查您是否有权访问该位置。
ALTER TABLE userlogs ADD
PARTITION (..., day='01') LOCATION 's3://userlogs/year=2016/month=01/day=01/'
PARTITION (..., day='restricted') LOCATION 's3://userlogs/year=2016/month=01/day=restricted/';
这意味着元存储中指向此类位置的单个分区可能会失败 SELECT
SELECT COUNT(*) FROM userlogs -- error(s): Access Denied ...
除非您在 WHERE
子句中排除它:
SELECT COUNT(*) FROM userlogs WHERE day != 'restricted'
或者用DROP PARTITION
删除这个分区
ALTER TABLE userlogs DROP PARTITION (..., day='restricted');
-- Followed by, which will succeed
SELECT COUNT(*) FROM userlogs
分区值不必与位置相同(这是预期的),可以使用不同的值同时指向同一位置。
ALTER TABLE userlogs ADD
PARTITION (..., day='01') LOCATION 's3://userlogs/year=2016/month=01/day=01/'
PARTITION (..., day='first') LOCATION 's3://userlogs/year=2016/month=01/day=01/';
现在如果我们使用 WHERE
子句查询,我们将得到相同的结果。
SELECT COUNT(*) FROM userlogs WHERE day = '01'
SELECT COUNT(*) FROM userlogs WHERE day = 'first'
我们假设它们都输出10。但是,如果您在没有 WHERE
子句的情况下进行查询,则输出将为 20,因为 Athena 对同一位置进行了两次扫描。
我有一个按天分区的 s3 目录结构 s3://userlogs/year=YYYY/month=MM/day=DD/
我有服务器不断地用文件填充当天的目录——它们每天添加大约 6,000 个文件。添加每个文件后,我想更新 Glue 数据存储中的 table userlogs
以包含它。
问题是 AWS glue 只为我们提供了一种使用像
这样的命令将全新分区(及其相应目录)添加到 table 的方法ALTER TABLE userlogs ADD
PARTITION (year = '2016', month = '01', day = '01) LOCATION 's3://userlogs/year=2016/month=01/day=02/'
但是,每次我 运行 我假设 Glue 需要扫描该目录中所有可能的数千个文件的命令。
我真正想要的是某种 method/command 可以执行以下操作:
ALTER TABLE userlogs UPDATE
PARTITION (year = '2016', month = '01', day = '01) ADD FILE's3://userlogs/year=2016/month=01/day=02/todays_file_no_3423.parquet.gz'
有没有什么方法可以实现这个目标而不涉及重构我的数据存储方式?
命令ALTER TABLE ...
不会扫描您在 S3 中的数据(因此它是免费的)。它只是定义有关您在 AWS Glue 数据目录中的数据的元信息,即应该可以使用 Athena 查询搜索的 S3 中文件的位置,因此,此命令完成所需的时间不到一秒。
因此,您不需要单独添加文件,只要您在 glue metastore 中有一个分区 "points" 到这些文件所在的 S3 位置。所以之后
ALTER TABLE userlogs ADD
PARTITION (year = '2016', month = '01', day = '01')
LOCATION 's3://userlogs/year=2016/month=01/day=01/';
您可以将任意数量的文件添加到 s3://userlogs/year=2016/month=01/day=01/
,它们的所有内容都可以通过 Athena 进行查询。
补充说明 TL;DR
不确定 ALTER TABLE userlogs ADD PARTITION ...
的以下行为是否符合预期,但是:
只检查S3 bucket是否存在,不检查S3全路径。所以下面的DDL语句会成功
ALTER TABLE userlogs ADD PARTITION (..., day='01') LOCATION 's3://userlogs/year=2016/month=01/day=01/' PARTITION (..., day='wrong') LOCATION 's3://userlogs/year=2016/month=01/day=wrong_path/';
正常查询也会成功,但结果不同,因为错误路径中没有文件
SELECT COUNT(*) FROM userlogs WHERE day = '01' -- outputs some value SELECT COUNT(*) FROM userlogs WHERE day = 'wrong' -- outputs 0
它不会检查您是否有权访问该位置。
ALTER TABLE userlogs ADD PARTITION (..., day='01') LOCATION 's3://userlogs/year=2016/month=01/day=01/' PARTITION (..., day='restricted') LOCATION 's3://userlogs/year=2016/month=01/day=restricted/';
这意味着元存储中指向此类位置的单个分区可能会失败
SELECT
SELECT COUNT(*) FROM userlogs -- error(s): Access Denied ...
除非您在
WHERE
子句中排除它:SELECT COUNT(*) FROM userlogs WHERE day != 'restricted'
或者用
删除这个分区DROP PARTITION
ALTER TABLE userlogs DROP PARTITION (..., day='restricted'); -- Followed by, which will succeed SELECT COUNT(*) FROM userlogs
分区值不必与位置相同(这是预期的),可以使用不同的值同时指向同一位置。
ALTER TABLE userlogs ADD PARTITION (..., day='01') LOCATION 's3://userlogs/year=2016/month=01/day=01/' PARTITION (..., day='first') LOCATION 's3://userlogs/year=2016/month=01/day=01/';
现在如果我们使用
WHERE
子句查询,我们将得到相同的结果。SELECT COUNT(*) FROM userlogs WHERE day = '01' SELECT COUNT(*) FROM userlogs WHERE day = 'first'
我们假设它们都输出10。但是,如果您在没有
WHERE
子句的情况下进行查询,则输出将为 20,因为 Athena 对同一位置进行了两次扫描。