

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Amazon Athena 使用 SQL 查询文件
<a name="tutorial-query-data-with-athena"></a>

企业系统经常生成基于文件的输出（日志导出、事务提取、清单快照、系统间文件丢弃），这些输出存放在 NFS 或 SMB 文件共享上。

在 FSx for ONTAP 卷上连接了 Amazon S3 接入点后，Amazon Athena 会就地查询文件。您的应用程序和用户继续像往常一样通过 NFS 或 SMB 向卷写入数据，分析人员通过接入点对这些数据运行标准 SQL。由于可以通过 NFS、SMB 和 Amazon S3 API 同时访问适用于 ONTAP 卷的 FSx，因此同一个文件可以由一个协议生成，而另一个协议可以使用，而无需副本。

在本教程中，您将通过 Amazon S3 接入点将示例数据集上传到您的 FSx for ONTAP 卷，在中注册该数据集，然后使用 Amazon Athena 进行查询。 AWS Glue Data Catalog

**注意**  
本教程大约需要 **20 到 30 分钟**才能完成。 AWS 服务 使用者会对您创建的资源产生费用。如果您及时完成所有步骤，包括**清理**部分，则美国东部（弗吉尼亚北部）的预期费用将低于 **1美元** AWS 区域。该估算值不包括 FSx 对 ONTAP 容量本身的持续收费。

## 先决条件
<a name="tutorial-athena-prerequisites"></a>

在开始之前，请确保您具有以下各项：
+ 连接了 Amazon S3 接入点的 ONTAP 卷的 FSx。接入点必须具有**互联网**网络来源。有关创建接入点的说明，请参阅[创建接入点](fsxn-creating-access-points.md)。
+ 配置了查询结果位置的 Athena 工作组。Athena 将查询结果写入亚马逊 S3 存储桶，而不是 ONTAP 卷的 FSx。**如果您没有工作组，则可以使用该`primary`工作组并在 Athena 控制台的 “设置” 下配置结果位置。**有关更多信息，请参阅 A *mazon Athena 用户指南*中的[管理工作组](https://docs.aws.amazon.com/athena/latest/ug/workgroups-create-update-delete.html)。
+ 附 AWS Glue 带`AWSGlueServiceRole`托管策略的 IAM 角色和授予访问您的 Amazon S3 接入点访问权限的内联策略。如果没有，请按以下步骤操作。

  1. 将以下信任策略另存为`glue-trust-policy.json`。它 AWS Glue 允许扮演这个角色。

     ```
     {
         "Version": "2012-10-17", 		 	 	 
         "Statement": [
             {
                 "Effect": "Allow",
                 "Principal": {"Service": "glue.amazonaws.com"},
                 "Action": "sts:AssumeRole"
             }
         ]
     }
     ```

  1. 将以下权限策略另存为`glue-s3-policy.json`。它授予访问接入点的权限。用您的值替换`{{region}}``{{account-id}}`、和`{{access-point-name}}`。

     ```
     {
         "Version": "2012-10-17", 		 	 	 
         "Statement": [
             {
                 "Effect": "Allow",
                 "Action": [
                     "s3:GetObject",
                     "s3:ListBucket"
                 ],
                 "Resource": [
                     "arn:aws:s3:{{region}}:{{account-id}}:accesspoint/{{access-point-name}}",
                     "arn:aws:s3:{{region}}:{{account-id}}:accesspoint/{{access-point-name}}/object/*"
                 ]
             }
         ]
     }
     ```

  1. 创建角色并附加策略。

     ```
     $ aws iam create-role \
         --role-name {{fsxn-tutorial-glue-role}} \
         --assume-role-policy-document file://glue-trust-policy.json
     
     aws iam attach-role-policy \
         --role-name {{fsxn-tutorial-glue-role}} \
         --policy-arn arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
     
     aws iam put-role-policy \
         --role-name {{fsxn-tutorial-glue-role}} \
         --policy-name s3-access-point-policy \
         --policy-document file://glue-s3-policy.json
     ```
+ 运行 Athena 查询和访问数据目录的 IAM 权限 AWS Glue 。

**重要**  
Amazon S3 接入点必须使用互联网网络来源。Athena 通过托管基础设施访问 Amazon S3，而不是从您的 VPC。具有 VPC 网络来源的接入点会拒绝来自 Athena 的请求。

## 步骤 1：将 ONTAP 卷的示例数据上传到您的 FSx
<a name="tutorial-athena-upload-data"></a>

本教程使用[纽约市出租车和豪华轿车委员会 (TLC) 旅行记录数据](https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page)，这是纽约市出租车旅行的公开数据集。数据采用 Apache Parquet 格式，这是一种列式格式，Athena 可以高效地查询该格式。

下载一个月的黄色出租车出行数据，然后通过 Amazon S3 接入点将其上传到您的 FSx 以获取 ONTAP 音量。

```
$ curl -O https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2024-01.parquet
```

使用接入点别名将文件上传到您的 FSx for ONTAP 卷。`{{my-ap-alias-ext-s3alias}}`替换为您的接入点别名。

```
$ aws s3 cp yellow_tripdata_2024-01.parquet \
    s3://{{my-ap-alias-ext-s3alias}}/taxi-data/yellow_tripdata_2024-01.parquet
```

验证文件是否可通过接入点访问。

```
$ aws s3 ls s3://{{my-ap-alias-ext-s3alias}}/taxi-data/
2024-01-23 02:18:13   49961641 yellow_tripdata_2024-01.parquet
```

## 步骤 2：在中创建数据库 AWS Glue Data Catalog
<a name="tutorial-athena-create-database"></a>

在中创建数据库 AWS Glue Data Catalog 以保存表元数据。您可以使用控制 AWS Glue 台、Athena 查询编辑器或. AWS CLI

**AWS Glue console**

1. 打开 AWS Glue 控制台，网址为[https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)。

1. 在导航窗格中的**数据目录**下，选择**数据库**。

1. 选择 **Add database**（添加数据库）。

1. 对于**名称**，请输入 `{{fsxn_taxi_demo}}`。

1. 选择**创建数据库**。

**Athena 查询编辑器或 AWS CLI**

```
$ aws athena start-query-execution \
    --query-string "CREATE DATABASE IF NOT EXISTS {{fsxn_taxi_demo}}" \
    --work-group {{primary}}
```

## 步骤 3：将数据注册到 AWS Glue Data Catalog
<a name="tutorial-athena-register-data"></a>

您可以在 Athena 中使用 AWS Glue 爬虫（推荐）或手动`CREATE EXTERNAL TABLE`语句注册数据。

### 选项 A：使用 AWS Glue 爬虫（推荐）
<a name="tutorial-athena-glue-crawler"></a>

C AWS Glue rawler 会自动发现您的数据架构并在中创建表。 AWS Glue Data Catalog这是推荐的方法，因为爬虫会从 Parquet 文件元数据中推断出正确的列类型。

1. 创建指向接入点别名的爬虫。`{{my-ap-alias-ext-s3alias}}`替换为您的接入点别名和 `{{my-glue-role-arn}}` I AWS Glue AM 角色的 ARN。

   ```
   $ aws glue create-crawler \
       --name {{fsxn-taxi-crawler}} \
       --role {{my-glue-role-arn}} \
       --database-name {{fsxn_taxi_demo}} \
       --targets '{"S3Targets": [{"Path": "s3://{{my-ap-alias-ext-s3alias}}/taxi-data/"}]}'
   ```

1. 运行 爬网程序。

   ```
   $ aws glue start-crawler --name {{fsxn-taxi-crawler}}
   ```

1. 检查爬虫状态。爬行程序通常在一到两分钟内完成。

   ```
   $ aws glue get-crawler --name {{fsxn-taxi-crawler}} \
       --query "Crawler.{State:State,Status:LastCrawl.Status}"
   ```

   爬网程序完成后，状态为`READY`，状态为`SUCCEEDED`。Crawler 在`fsxn_taxi_demo`数据库中创建一个名为`taxi_data`（源自文件夹名称）的表。

### 选项 B：在 Athena 中手动创建表
<a name="tutorial-athena-manual-ddl"></a>

如果您已经知道数据的架构，则可以使用语句直接在 Athena 中创建表。`CREATE EXTERNAL TABLE`在`LOCATION`子句中使用接入点别名。

```
CREATE EXTERNAL TABLE fsxn_taxi_demo.yellow_taxi_trips (
    VendorID bigint,
    tpep_pickup_datetime timestamp,
    tpep_dropoff_datetime timestamp,
    passenger_count bigint,
    trip_distance double,
    RatecodeID bigint,
    store_and_fwd_flag string,
    PULocationID bigint,
    DOLocationID bigint,
    payment_type bigint,
    fare_amount double,
    extra double,
    mta_tax double,
    tip_amount double,
    tolls_amount double,
    improvement_surcharge double,
    total_amount double,
    congestion_surcharge double,
    Airport_fee double
)
STORED AS PARQUET
LOCATION 's3://{{my-ap-alias-ext-s3alias}}/taxi-data/'
```

**注意**  
列类型必须与 Parquet 文件中的类型相匹配。对于这个数据集，像`passenger_count`和`VendorID`这样的字段以 `bigint` (INT64) 的形式存储在 Parquet 文件中，而不是`double`。如果类型不匹配，Athena 将返回错误。`HIVE_BAD_DATA`使用 AWS Glue 爬虫（选项 A）可以避免此问题，因为爬虫会自动推断出正确的类型。

## 第 4 步：查询您的数据
<a name="tutorial-athena-query-data"></a>

打开 Athena 查询编辑器或使用 AWS CLI 对您的 FSx 运行 SQL 查询，获取 ONTAP 数据。以下示例使用由 AWS Glue Crawler (`taxi_data`) 创建的表。如果您手动创建了表，请`taxi_data`替换为`yellow_taxi_trips`。

**计算行程总数并计算平均值**

```
SELECT
    COUNT(*) AS total_trips,
    ROUND(AVG(trip_distance), 2) AS avg_distance_miles,
    ROUND(AVG(total_amount), 2) AS avg_total_usd,
    ROUND(AVG(passenger_count), 1) AS avg_passengers
FROM fsxn_taxi_demo.taxi_data
```

输出示例：


| 行程总数 | 平均距离\_英里 | avg\_total\_USD | 平均乘客数 | 
| --- | --- | --- | --- | 
| 2964624 | 3.65 | 26.80 | 1.3 | 

**查找最繁忙的接送时间**

```
SELECT
    HOUR(tpep_pickup_datetime) AS pickup_hour,
    COUNT(*) AS trip_count,
    ROUND(AVG(total_amount), 2) AS avg_fare
FROM fsxn_taxi_demo.taxi_data
GROUP BY HOUR(tpep_pickup_datetime)
ORDER BY trip_count DESC
LIMIT 5
```

**查找收入最高的取货地点**

```
SELECT
    PULocationID AS pickup_location,
    COUNT(*) AS trip_count,
    ROUND(SUM(total_amount), 2) AS total_revenue
FROM fsxn_taxi_demo.taxi_data
GROUP BY PULocationID
ORDER BY total_revenue DESC
LIMIT 10
```

## 注意事项
<a name="tutorial-athena-considerations"></a>
+ **Read-only 访问。**Athena 通过接入点从 FSx 读取 ONTAP 卷的数据。对于 ONTAP 卷，Athena 的查询结果会写入 Amazon S3 结果存储桶，而不是写回 FSx。
+ **需要互联网来源。**Athena 从您的 VPC 外部的托管基础设施访问 Amazon S3。`aws:SourceVpc`和`aws:SourceVpce`条件键不适用于 Athena 请求。您必须使用源自互联网的接入点。
+ **文件格式。**Athena 支持 Parquet、ORC、JSON、CSV 和其他格式。Parquet 和 ORC 等列式格式可提供最佳的查询性能，因为 Athena 只读取查询中引用的列。
+ **文件系统用户权限。**与接入点关联的文件系统用户必须对所查询的文件具有读取权限。
+ **AWS Glue Data Catalog 桌子是可重复使用的。**在中注册表格后 AWS Glue Data Catalog，其他与之集成的 AWS 分析服务即可使用该表，例如亚马逊 Redshift Spectrum AWS Glue Data Catalog、Amazon EMR 和 ETL 作业。 AWS Glue 

## 清理
<a name="tutorial-athena-clean-up"></a>

为避免持续收费，请删除您在本教程中创建的资源。

1. 删除 Athena 表和数据库。

   ```
   DROP TABLE IF EXISTS fsxn_taxi_demo.taxi_data;
   DROP TABLE IF EXISTS fsxn_taxi_demo.yellow_taxi_trips;
   DROP DATABASE IF EXISTS fsxn_taxi_demo CASCADE;
   ```

1. 删除 AWS Glue 爬虫。

   ```
   $ aws glue delete-crawler --name {{fsxn-taxi-crawler}}
   ```

1. 从 FSx 中删除 ONTAP 卷的示例数据。

   ```
   $ aws s3 rm s3://{{my-ap-alias-ext-s3alias}}/taxi-data/yellow_tripdata_2024-01.parquet
   ```