跳至主要内容

如何从 S3 存储桶中导入 Parquet 文件

·阅读时间:3 分钟

以下是使用 S3 表引擎读取 parquet 文件的一些基本知识。

  • 为 IAM 服务用户创建访问密钥和密钥。普通登录用户通常不起作用,因为它们可能已使用 MFA 策略进行配置。

  • 将策略上的权限设置为允许服务用户访问存储桶和文件夹。

以下是一个非常简单的示例,您可以在将示例应用于实际数据之前使用它来测试成功访问 parquet 文件的机制。

如果您需要创建用户和存储桶的示例,您可以按照前两部分(创建用户和创建存储桶)进行操作:https://clickhouse.ac.cn/docs/en/guides/sre/configuring-s3-for-clickhouse-use/

我使用了此示例文件:https://github.com/Teradata/kylo/tree/master/samples/sample-data/parquet 并将其上传到我的测试存储桶

您可以在存储桶上设置类似于此的策略:(根据需要调整,此策略的权限相当开放,但将有助于测试。您可以根据需要缩小权限)

{
"Version": "2012-10-17",
"Id": "Policy123456",
"Statement": [
{
"Sid": "abc123",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::1234567890:user/mars-s3-user"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::mars-doc-test",
"arn:aws:s3:::mars-doc-test/*"
]
}
]
}

您可以使用 S3 表引擎使用这种类型的语法运行查询:https://clickhouse.ac.cn/docs/en/sql-reference/table-functions/s3/

clickhouse-cloud :)  select count(*) from s3('https://mars-doc-test.s3.amazonaws.com/s3-parquet-test/userdata1.parquet','ABC123', 'abc+123', 'Parquet', 'first_name String');

SELECT count(*)
FROM s3('https://mars-doc-test.s3.amazonaws.com/s3-parquet-test/userdata1.parquet', 'ABC123', 'abc+123', 'Parquet', 'first_name String')

Query id: fd4f1193-d604-4ac0-9a46-bdd2d5e14727

┌─count()─┐
│ 1000 │
└─────────┘

1 row in set. Elapsed: 1.274 sec. Processed 1.00 thousand rows, 14.64 KB (784.81 rows/s., 11.49 KB/s.)

parquet 格式的数据类型参考在此处:https://clickhouse.ac.cn/docs/en/interfaces/formats/#data-format-parquet

将数据导入到本地 ClickHouse 表中

创建表,类似于此(只选择 parquet 文件中的几个列)

clickhouse-cloud :) CREATE TABLE my_parquet_table (id UInt64, first_name String) ENGINE = MergeTree ORDER BY id;

CREATE TABLE my_parquet_table
(
`id` UInt64,
`first_name` String
)
ENGINE = MergeTree
ORDER BY id

Query id: 412e3994-bf8e-444e-ac43-a7c82642b7da

Ok.

0 rows in set. Elapsed: 0.600 sec.

从 S3 存储桶中选择数据以插入到新表中

clickhouse-cloud :) INSERT INTO my_parquet_table (id, first_name) SELECT id, first_name FROM s3('https://mars-doc-test.s3.amazonaws.com/s3-parquet-test/userdata1.parquet', 'ABC123','abc+123', 'Parquet', 'id UInt64, first_name String') FORMAT Parquet

INSERT INTO my_parquet_table (id, first_name) SELECT
id,
first_name
FROM s3('https://mars-doc-test.s3.amazonaws.com/s3-parquet-test/userdata1.parquet', 'ABC123', 'abc+123', 'Parquet', 'id UInt64, first_name String')

Query id: c3cdc871-f338-462d-8797-6751b45a0b58

Ok.

0 rows in set. Elapsed: 1.220 sec. Processed 1.00 thousand rows, 22.64 KB (819.61 rows/s., 18.56 KB/s.)

验证导入

clickhouse-cloud :) SELECT * FROM my_parquet_table LIMIT 10;

SELECT *
FROM my_parquet_table
LIMIT 10

Query id: 1ccf59dd-d804-46a9-aadd-ed5c57b9e1a0

┌─id─┬─first_name─┐
│ 1 │ Amanda │
│ 2 │ Albert │
│ 3 │ Evelyn │
│ 4 │ Denise │
│ 5 │ Carlos │
│ 6 │ Kathryn │
│ 7 │ Samuel │
│ 8 │ Harry │
│ 9 │ Jose │
│ 10 │ Emily │
└────┴────────────┘

准备导入真实数据时,可以使用通配符和范围等特殊语法来指定存储桶中的文件夹、子文件夹和文件。我建议先过滤几个目录和文件以测试导入,例如,某个特定年份、几个月以及某些日期范围。

除了这里的路径选项外,最新发布的语法是 **,它指定递归地指定所有子目录。https://clickhouse.ac.cn/docs/en/sql-reference/table-functions/s3/

例如,假设路径和存储桶结构类似于:https://your_s3_bucket.s3.amazonaws.com/<your_folder>/<year>/<month>/<day>/<filename>.parquet https://mars-doc-test.s3.amazonaws.com/system_logs/2022/11/01/my-app-logs-0001.parquet

这将获取 2021-2022 年每月的第一天上的所有文件:https://mars-doc-test.s3.amazonaws.com/system_logs/{2021-2022}/**/01/*.parquet