

# 使用 AWS Glue 对 Amazon S3 表运行 ETL 任务
<a name="s3-tables-integrating-glue"></a>

AWS Glue 是一项无服务器数据集成服务，可让使用分析功能的用户轻松发现、准备、移动和集成来自多个来源的数据。可以使用 AWS Glue 运行提取、转换、加载（ETL）管道，来将数据加载到数据湖中。有关 AWS Glue 的更多信息，请参阅《*AWS Glue 开发人员指南*》中的[什么是 AWS Glue？](https://docs.aws.amazon.com//glue/latest/dg/what-is-glue.html)。

AWS Glue 作业将封装连接到源数据的脚本，处理该脚本，然后将其写入数据目标。通常，作业运行提取、转换和加载 (ETL) 脚本。作业可以运行专为 Apache Spark 运行时环境设计的脚本。您可以监控作业运行以了解运行时指标（例如完成状态、持续时间和开始时间）。

您可以使用 AWS Glue 作业来处理 S3 表中的数据，方法是通过与 AWS 分析服务的集成连接到表，或者直接使用 Amazon S3 表类数据存储服务 Iceberg REST 端点或适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录进行连接。本指南涵盖了开始将 AWS Glue 与 S3 表类数据存储服务结合使用的基本步骤，包括：

**Topics**
+ [步骤 1：先决条件](#glue-etl-prereqs)
+ [步骤 2：创建用于连接到表存储桶的脚本](#glue-etl-script)
+ [步骤 3：创建用于查询表的 AWS Glue 任务](#glue-etl-job)

根据特定的 AWS Glue ETL 任务要求选择访问方法：
+ **AWS 分析服务集成（建议）**：当您需要跨多项 AWS 分析服务进行集中式元数据管理、需要利用现有 AWS Glue Data Catalog 权限和 Lake Formation 的精细访问控制功能，或者正在构建与 Athena 或 Amazon EMR AWS 等其它服务集成的生产 ETL 管道时，建议使用此访问方法。
+ **Amazon S3 表类数据存储服务 Iceberg REST 端点**：当您需要从支持 Apache Iceberg 的第三方查询引擎连接到 S3 表、构建需要直接 REST API 访问的自定义 ETL 应用程序，或者需要在不依赖 AWS Glue Data Catalog 的情况下控制目录操作时，建议使用此访问方法。
+ **适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录**：仅用于需要 Java 客户端库的传统应用程序或特定编程方案。由于额外的 `JAR` 依赖项管理和复杂性，因此不建议将此方法用于新的 AWS Glue ETL 任务实现。

**注意**  
[AWS Glue 版本 5.0 或更高版本](https://docs.aws.amazon.com//glue/latest/dg/release-notes.html)支持 S3 表类数据存储服务。

## 步骤 1：先决条件
<a name="glue-etl-prereqs"></a>

在从 AWS Glue 任务中查询表之前，必须配置 AWS Glue 可用来运行该任务的 IAM 角色。选择访问方法以查看该方法的特定先决条件。

------
#### [ AWS analytics services integration (Recommended) ]

使用 S3 表类数据存储服务 AWS 分析集成来运行 AWS Glue 任务所需的先决条件。
+ [将表存储桶与 AWS 分析服务集成](s3-tables-integrating-aws.md)。
+ [为 AWS Glue 创建 IAM 角色。](https://docs.aws.amazon.com//glue/latest/dg/create-an-iam-role.html)
  + 将 `AmazonS3TablesFullAccess` 托管式策略附加到角色。
  + 将 `AmazonS3FullAccess` 托管式策略附加到角色。

------
#### [ Amazon S3 Tables Iceberg REST endpoint ]

使用 Amazon S3 表类数据存储服务 Iceberg REST 端点来运行 AWS Glue ETL 任务的先决条件。
+ [为 AWS Glue 创建 IAM 角色。](https://docs.aws.amazon.com//glue/latest/dg/create-an-iam-role.html)
  + 将 `AmazonS3TablesFullAccess` 托管式策略附加到角色。
  + 将 `AmazonS3FullAccess` 托管式策略附加到角色。

------
#### [ Amazon S3 Tables Catalog for Apache Iceberg ]

先决条件使用适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录来运行 AWS Glue ETL 任务。
+ [为 AWS Glue 创建 IAM 角色。](https://docs.aws.amazon.com//glue/latest/dg/create-an-iam-role.html)
  + 将 `AmazonS3TablesFullAccess` 托管式策略附加到角色。
  + 将 `AmazonS3FullAccess` 托管式策略附加到角色。
  + 要使用适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录，您需要下载客户端目录 JAR 并将其上传到 S3 存储桶。

****下载目录 JAR****

    1. 在 [Maven Central](https://mvnrepository.com/artifact/software.amazon.s3tables/s3-tables-catalog-for-iceberg-runtime) 上检查最新版本。您可以使用浏览器或使用以下命令从 Maven Central 下载 JAR。请务必将*版本号*替换为最新版本。

       ```
       wget https://repo1.maven.org/maven2/software/amazon/s3tables/s3-tables-catalog-for-iceberg-runtime/0.1.5/s3-tables-catalog-for-iceberg-runtime-0.1.5.jar                       
       ```

    1. 将下载的 JAR 上传到 AWS Glue IAM 角色可以访问的 S3 存储桶。您可以使用以下 AWS CLI 命令来上传 JAR。请务必将*版本号*替换为最新版本，并将*存储桶名称*和*路径*替换为您自己的信息。

       ```
       aws s3 cp s3-tables-catalog-for-iceberg-runtime-0.1.5.jar s3://amzn-s3-demo-bucket/jars/
       ```

------

## 步骤 2：创建用于连接到表存储桶的脚本
<a name="glue-etl-script"></a>

要在运行 AWS Glue ETL 作业时访问表数据，可以为 Apache Iceberg 配置一个 Spark 会话，用于连接到 S3 表存储桶。可以修改现有脚本以连接到表存储桶或创建新脚本。有关创建 AWS Glue 脚本的更多信息，请参阅《AWS Glue 开发人员指南》**中的[教程：编写 AWS Glue for Spark 脚本](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-intro-tutorial.html)。

可以将会话配置为通过以下任一 S3 表类数据存储服务访问方法连接到表存储桶：
+ S3 表类数据存储服务 AWS 分析服务集成（建议）
+ Amazon S3 表类数据存储服务 Iceberg REST 端点
+ 适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录

从以下访问方法中进行选择，以查看设置说明和配置示例。

------
#### [ AWS analytics services integration (Recommended) ]

作为使用 AWS 分析服务集成在 AWS Glue 上使用 Spark 查询表的先决条件，您必须[将表存储桶与 AWS 分析服务进行集成](s3-tables-integrating-aws.md)

可以通过作业中的 Spark 会话或交互式会话中的 AWS Glue Studio 魔法来配置与表存储桶的连接。要使用以下示例，请将*占位符值*替换为您自己的表存储桶的信息。

**使用 PySpark 脚本**  
在 PySpark 脚本中使用以下代码段，以便将 AWS Glue 作业配置为使用集成连接到表存储桶。  

```
spark = SparkSession.builder.appName("SparkIcebergSQL") \
    .config("spark.jars.packages", "org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.4.2") \
    .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
    .config("spark.sql.defaultCatalog","s3tables") \
    .config("spark.sql.catalog.s3tables", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.s3tables.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog") \
    .config("spark.sql.catalog.s3tables.glue.id", "111122223333:s3tablescatalog/amzn-s3-demo-table-bucket") \
    .config("spark.sql.catalog.s3tables.warehouse", "s3://amzn-s3-demo-table-bucket/warehouse/") \
    .getOrCreate()
```

**使用交互式 AWS Glue 会话**  
如果您将交互式笔记本会话与 AWS Glue 5.0 结合使用，请在执行代码之前，在单元格中使用 `%%configure` 魔法指定相同的配置。  

```
%%configure
{"conf": "spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions --conf spark.sql.defaultCatalog=s3tables --conf spark.sql.catalog.s3tables=org.apache.iceberg.spark.SparkCatalog --conf spark.sql.catalog.s3tables.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog --conf spark.sql.catalog.s3tables.glue.id=111122223333:s3tablescatalog/amzn-s3-demo-table-bucket --conf spark.sql.catalog.s3tables.warehouse=s3://amzn-s3-demo-table-bucket/warehouse/"}
```

------
#### [ Amazon S3 Tables Iceberg REST endpoint ]

可以通过作业中的 Spark 会话或交互式会话中的 AWS Glue Studio 魔法来配置与表存储桶的连接。要使用以下示例，请将*占位符值*替换为您自己的表存储桶的信息。

**使用 PySpark 脚本**  
在 PySpark 脚本中使用以下代码段，以便将 AWS Glue 作业配置为使用端点连接到表存储桶。  

```
spark = SparkSession.builder.appName("glue-s3-tables-rest") \
    .config("spark.jars.packages", "org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.4.2") \
    .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
    .config("spark.sql.defaultCatalog", "s3_rest_catalog") \
    .config("spark.sql.catalog.s3_rest_catalog", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.s3_rest_catalog.type", "rest") \
    .config("spark.sql.catalog.s3_rest_catalog.uri", "https://s3tables.Region.amazonaws.com/iceberg") \
    .config("spark.sql.catalog.s3_rest_catalog.warehouse", "arn:aws:s3tables:Region:111122223333:bucket/amzn-s3-demo-table-bucket") \
    .config("spark.sql.catalog.s3_rest_catalog.rest.sigv4-enabled", "true") \
    .config("spark.sql.catalog.s3_rest_catalog.rest.signing-name", "s3tables") \
    .config("spark.sql.catalog.s3_rest_catalog.rest.signing-region", "Region") \
    .config('spark.sql.catalog.s3_rest_catalog.io-impl','org.apache.iceberg.aws.s3.S3FileIO') \
    .config('spark.sql.catalog.s3_rest_catalog.rest-metrics-reporting-enabled','false') \
    .getOrCreate()
```

**使用交互式 AWS Glue 会话**  
如果您将交互式笔记本会话与 AWS Glue 5.0 结合使用，请在执行代码之前，在单元格中使用 `%%configure` 魔法指定相同的配置。将占位符值 替换为您自己的表存储桶的信息。  

```
%%configure
{"conf": "spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions --conf spark.sql.defaultCatalog=s3_rest_catalog --conf spark.sql.catalog.s3_rest_catalog=org.apache.iceberg.spark.SparkCatalog --conf spark.sql.catalog.s3_rest_catalog.type=rest --conf spark.sql.catalog.s3_rest_catalog.uri=https://s3tables.Region.amazonaws.com/iceberg --conf spark.sql.catalog.s3_rest_catalog.warehouse=arn:aws:s3tables:Region:111122223333:bucket/amzn-s3-demo-table-bucket --conf spark.sql.catalog.s3_rest_catalog.rest.sigv4-enabled=true --conf spark.sql.catalog.s3_rest_catalog.rest.signing-name=s3tables --conf spark.sql.catalog.s3_rest_catalog.rest.signing-region=Region --conf spark.sql.catalog.s3_rest_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO --conf spark.sql.catalog.s3_rest_catalog.rest-metrics-reporting-enabled=false"}
```

------
#### [ Amazon S3 Tables Catalog for Apache Iceberg ]

作为使用适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录连接到表的先决条件，您必须先下载最新的目录 jar 并将其上传到 S3 存储桶。然后，在创建作业时，将指向客户端目录 JAR 的路径添加为一个特殊参数。有关 AWS Glue 中作业参数的更多信息，请参阅《AWS Glue 开发人员指南》**中的 [AWS Glue 作业中使用的特殊参数](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html)。

可以通过作业中的 Spark 会话或交互式会话中的 AWS Glue Studio 魔法来配置与表存储桶的连接。要使用以下示例，请将*占位符值*替换为您自己的表存储桶的信息。

**使用 PySpark 脚本**  
在 PySpark 脚本中使用以下代码段，以便将 AWS Glue 作业配置为使用 JAR 连接到表存储桶。将占位符值 替换为您自己的表存储桶的信息。  

```
spark = SparkSession.builder.appName("glue-s3-tables") \
    .config("spark.jars.packages", "org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.4.2") \
    .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
    .config("spark.sql.defaultCatalog", "s3tablesbucket") \
    .config("spark.sql.catalog.s3tablesbucket", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.s3tablesbucket.catalog-impl", "software.amazon.s3tables.iceberg.S3TablesCatalog") \
    .config("spark.sql.catalog.s3tablesbucket.warehouse", "arn:aws:s3tables:Region:111122223333:bucket/amzn-s3-demo-table-bucket") \
    .getOrCreate()
```

**使用交互式 AWS Glue 会话**  
如果您将交互式笔记本会话与 AWS Glue 5.0 结合使用，请在执行代码之前，在单元格中使用 `%%configure` 魔法指定相同的配置。将占位符值 替换为您自己的表存储桶的信息。  

```
%%configure
{"conf": "spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions --conf spark.sql.defaultCatalog=s3tablesbucket --conf spark.sql.catalog.s3tablesbucket=org.apache.iceberg.spark.SparkCatalog --conf spark.sql.catalog.s3tablesbucket.catalog-impl=software.amazon.s3tables.iceberg.S3TablesCatalog --conf spark.sql.catalog.s3tablesbucket.warehouse=arn:aws:s3tables:Region:111122223333:bucket/amzn-s3-demo-table-bucket", "extra-jars": "s3://amzn-s3-demo-bucket/jars/s3-tables-catalog-for-iceberg-runtime-0.1.5.jar"}
```

------

### 示例脚本
<a name="w2aac20c25c31c19c13"></a>

以下示例 PySpark 脚本可用于测试通过 AWS Glue 作业来查询 S3 表。这些脚本连接到表存储桶，然后运行查询来执行以下操作：创建新的命名空间、创建示例表、向表中插入数据以及返回表数据。要使用这些脚本，请将*占位符值*替换为您自己的表存储桶的信息。

根据 S3 表类数据存储服务访问方法从以下脚本中进行选择。

------
#### [ S3 Tables integration with AWS analytics services ]

```
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("SparkIcebergSQL") \
    .config("spark.jars.packages", "org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.4.2") \
    .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
    .config("spark.sql.defaultCatalog","s3tables")
    .config("spark.sql.catalog.s3tables", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.s3tables.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog") \
    .config("spark.sql.catalog.s3tables.glue.id", "111122223333:s3tablescatalog/amzn-s3-demo-table-bucket") \
    .config("spark.sql.catalog.s3tables.warehouse", "s3://amzn-s3-demo-table-bucket/bucket/amzn-s3-demo-table-bucket") \
    .getOrCreate()

namespace = "new_namespace"
table = "new_table"

spark.sql("SHOW DATABASES").show()

spark.sql(f"DESCRIBE NAMESPACE {namespace}").show()

spark.sql(f"""
    CREATE TABLE IF NOT EXISTS {namespace}.{table} (
       id INT,
       name STRING,
       value INT
    )
""")

spark.sql(f"""
    INSERT INTO {namespace}.{table}
    VALUES 
       (1, 'ABC', 100),
       (2, 'XYZ', 200)
""")

spark.sql(f"SELECT * FROM {namespace}.{table} LIMIT 10").show()
```

------
#### [ Amazon S3 Tables Iceberg REST endpoint ]

```
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("glue-s3-tables-rest") \
    .config("spark.jars.packages", "org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.4.2") \
    .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
    .config("spark.sql.defaultCatalog", "s3_rest_catalog") \
    .config("spark.sql.catalog.s3_rest_catalog", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.s3_rest_catalog.type", "rest") \
    .config("spark.sql.catalog.s3_rest_catalog.uri", "https://s3tables.Region.amazonaws.com/iceberg") \
    .config("spark.sql.catalog.s3_rest_catalog.warehouse", "arn:aws:s3tables:Region:111122223333:bucket/amzn-s3-demo-table-bucket") \
    .config("spark.sql.catalog.s3_rest_catalog.rest.sigv4-enabled", "true") \
    .config("spark.sql.catalog.s3_rest_catalog.rest.signing-name", "s3tables") \
    .config("spark.sql.catalog.s3_rest_catalog.rest.signing-region", "Region") \
    .config('spark.sql.catalog.s3_rest_catalog.io-impl','org.apache.iceberg.aws.s3.S3FileIO') \
    .config('spark.sql.catalog.s3_rest_catalog.rest-metrics-reporting-enabled','false') \
    .getOrCreate()

namespace = "s3_tables_rest_namespace"
table = "new_table_s3_rest"

spark.sql("SHOW DATABASES").show()

spark.sql(f"DESCRIBE NAMESPACE {namespace}").show()

spark.sql(f"""
    CREATE TABLE IF NOT EXISTS {namespace}.{table} (
       id INT,
       name STRING,
       value INT
    )
""")

spark.sql(f"""
    INSERT INTO {namespace}.{table}
    VALUES 
       (1, 'ABC', 100),
       (2, 'XYZ', 200)
""")

spark.sql(f"SELECT * FROM {namespace}.{table} LIMIT 10").show()
```

------
#### [ Amazon S3 Tables Catalog for Apache Iceberg ]

```
from pyspark.sql import SparkSession

#Spark session configurations
spark = SparkSession.builder.appName("glue-s3-tables") \
    .config("spark.jars.packages", "org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.4.2") \
    .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
    .config("spark.sql.defaultCatalog", "s3tablesbucket") \
    .config("spark.sql.catalog.s3tablesbucket", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.s3tablesbucket.catalog-impl", "software.amazon.s3tables.iceberg.S3TablesCatalog") \
    .config("spark.sql.catalog.s3tablesbucket.warehouse", "arn:aws:s3tables:Region:111122223333:bucket/amzn-s3-demo-table-bucket") \
    .getOrCreate()

#Script
namespace = "new_namespace"
table = "new_table"

spark.sql(f"CREATE NAMESPACE IF NOT EXISTS s3tablesbucket.{namespace}")
spark.sql(f"DESCRIBE NAMESPACE {namespace}").show()

spark.sql(f"""
    CREATE TABLE IF NOT EXISTS {namespace}.{table} (
       id INT,
       name STRING,
       value INT
    )
""")

spark.sql(f"""
    INSERT INTO {namespace}.{table}
    VALUES 
       (1, 'ABC', 100),
       (2, 'XYZ', 200)
""")

spark.sql(f"SELECT * FROM {namespace}.{table} LIMIT 10").show()
```

------

## 步骤 3：创建用于查询表的 AWS Glue 任务
<a name="glue-etl-job"></a>

以下过程显示了如何设置连接到 S3 表存储桶的 AWS Glue 作业。您可以使用 AWS CLI 或将控制台与 AWS Glue Studio 脚本编辑器结合使用来完成此操作。有关更多信息，请参阅《AWS Glue 用户指南》**中的[在 AWS Glue 中编写任务](https://docs.aws.amazon.com/glue/latest/dg/author-job-glue.html)。

### 使用 AWS Glue Studio 脚本编辑器
<a name="tables-glue-studio-job"></a>

以下过程介绍了如何使用 AWS Glue Studio 脚本编辑器来创建用于查询 S3 表的 ETL 任务。

**先决条件**
+ [步骤 1：先决条件](#glue-etl-prereqs)
+ [步骤 2：创建用于连接到表存储桶的脚本](#glue-etl-script)

1. 通过 [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/) 打开 AWS Glue 控制台。

1. 在导航窗格中，选择 **ETL 任务**。

1. 选择**脚本编辑器**，然后选择**上传脚本**并上传您创建的用于查询 S3 表的 PySpark 脚本。

1. 选择**任务详细信息**选项卡，然后对于**基本属性**输入以下内容。
   + 对于**名称**，输入任务的名称。
   + 对于 **IAM 角色**，选择您为 AWS Glue 创建的角色。

1. （可选）如果您使用适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录访问方法，请展开**高级属性**，对于**从属 JAR 路径**，输入您作为先决条件上传到 S3 存储桶的客户端目录 jar 的 S3 URI。例如，s3://*amzn-s3-demo-bucket1*/*jars*/s3-tables-catalog-for-iceberg-runtime-*0.1.5*.jar

1. 选择**保存**以创建任务。

1. 选择**运行**以启动任务，然后在**运行**选项卡下查看任务状态。

### 使用 AWS CLI
<a name="tables-glue-cli-job"></a>

以下过程介绍了如何使用 AWS CLI 来创建用于查询 S3 表的 ETL 任务。要使用这些命令，请将*占位符值*替换为您自己的值。

**先决条件**
+ [步骤 1：先决条件](#glue-etl-prereqs)
+ [步骤 2：创建用于连接到表存储桶的脚本](#glue-etl-script)并将其上传到 S3 存储桶。

1. 创建 AWS Glue 任务。

   ```
   aws glue create-job \
   --name etl-tables-job \
   --role arn:aws:iam::111122223333:role/AWSGlueServiceRole \
   --command '{
       "Name": "glueetl",
       "ScriptLocation": "s3://amzn-s3-demo-bucket1/scripts/glue-etl-query.py",
       "PythonVersion": "3"
   }' \
   --default-arguments '{
       "--job-language": "python",
       "--class": "GlueApp"
   }' \
   --glue-version "5.0"
   ```
**注意**  
（可选）如果您使用适用于 Apache Iceberg 的 Amazon S3 表类数据存储服务目录访问方法，请使用 `--extra-jars` 参数将客户端目录 JAR 添加到 `--default-arguments` 中。添加参数时，将*输入占位符*替换为您自己的信息。  

   ```
                               "--extra-jars": "s3://amzn-s3-demo-bucket/jar-path/s3-tables-catalog-for-iceberg-runtime-0.1.5.jar" 
   ```

1. 启动任务。

   ```
   aws glue start-job-run \
   --job-name etl-tables-job
   ```

1. 要查看任务状态，请复制上一个命令中的运行 ID，然后将其输入到以下命令中。

   ```
   aws glue get-job-run --job-name etl-tables-job \
   --run-id jr_ec9a8a302e71f8483060f87b6c309601ea9ee9c1ffc2db56706dfcceb3d0e1ad
   ```