

# 在 AWS Glue 中使用 Avro 格式
<a name="aws-glue-programming-etl-format-avro-home"></a>

AWS Glue 从源中检索数据，并将数据写入以各种数据格式存储和传输的目标。如果您的数据以 Avro 数据格式存储或传输，本文档将向您介绍供您使用 AWS Glue 中的数据的可用功能。

AWS Glue 支持使用 Avro 格式。此格式是一种以性能为导向、基于行的数据格式。有关标准颁发机构对此格式的简介，请参阅 [Apache Avro 1.8.2 Documentation](https://avro.apache.org/docs/1.8.2/)（Apache Avro 1.8.2 文档）。

您可以使用 AWS Glue 从 Amazon S3 和流式传输源读取 Avro 文件，以及将 Avro 文件写入 Amazon S3。您可以读取并写入包含 S3 中的 Avro 文件的 `bzip2` 和 `gzip` 存档。此外，您还可以编写包含 Avro 文件的 `deflate`、`snappy` 和 `xz` 存档。请在 [S3 连接参数](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 上而非本页中讨论的配置中配置压缩行为。

下表显示了支持 Avro 格式选项的常用 AWS Glue 功能。


| 读取 | 写入 | 流式处理读取 | 对小文件进行分组 | 作业书签 | 
| --- | --- | --- | --- | --- | 
| 支持 | 支持 | 支持\$1 | 不支持 | 支持 | 

\$1受支持，但有限制。有关更多信息，请参阅 [Avro 串流源的注释和限制](add-job-streaming.md#streaming-avro-notes)。

## 示例：从 S3 读取 Avro 文件或文件夹
<a name="aws-glue-programming-etl-format-avro-read"></a>

**先决条件：**需要待读取的 Avro 文件或文件夹的 S3 路径 (`s3path`)。

**配置：**在函数选项中，请指定 `format="avro"`。在您的 `connection_options` 中，请使用 `paths` 键指定 `s3path`。您可以在 `connection_options` 中配置读取器与 S3 的交互方式。有关详细信息，请参阅 AWS Glue：[Amazon S3 连接选项参考](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 中的“Data format options for ETL inputs and outputs”（ETL 输入和输出的数据格式选项）。您可以配置读取器解释 `format_options` 中的 Avro 文件的方式。有关详细信息，请参阅 [Avro Configuration Reference](#aws-glue-programming-etl-format-avro-reference)（Avro 配置参考）。

以下 AWS Glue ETL 脚本显示了从 S3 读取 Avro 文件或文件夹的过程：

------
#### [ Python ]

在本示例中，使用 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 方法。

```
from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="avro"
)
```

------
#### [ Scala ]

在本示例中，使用 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 操作。

```
import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.GlueContext
import org.apache.spark.sql.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    val dynamicFrame = glueContext.getSourceWithFormat(
      connectionType="s3",
      format="avro",
      options=JsonOptions("""{"paths": ["s3://s3path"]}""")
    ).getDynamicFrame()
  }
```

------

## 示例：将 Avro 文件和文件夹写入 Amazon S3
<a name="aws-glue-programming-etl-format-avro-write"></a>

**先决条件：**您将需要一个初始化的 DataFrame（`dataFrame`）或 DynamicFrame（`dynamicFrame`）。您还需要预期 S3 输出路径 `s3path`。

**配置：**在函数选项中，请指定 `format="avro"`。在您的 `connection_options` 中，请使用 `paths` 键指定 `s3path`。您可以在 `connection_options` 中进一步修改编写器与 S3 的交互方式。有关详细信息，请参阅 AWS Glue：[Amazon S3 连接选项参考](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 中的“Data format options for ETL inputs and outputs”（ETL 输入和输出的数据格式选项）。您可以改变写入器在 `format_options` 中解释 Avro 文件的方式。有关详细信息，请参阅 [Avro Configuration Reference](#aws-glue-programming-etl-format-avro-reference)（Avro 配置参考）。

以下 AWS Glue ETL 脚本显示了将 Avro 文件或文件夹写入 Amazon S3 的过程。

------
#### [ Python ]

在本示例中，使用 [write\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options) 方法。

```
from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

glueContext.write_dynamic_frame.from_options(
    frame=dynamicFrame,
    connection_type="s3",
    format="avro",
    connection_options={
        "path": "s3://s3path"
    }
)
```

------
#### [ Scala ]

在本示例中，请使用 [getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat) 方法。

```
import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    glueContext.getSinkWithFormat(
      connectionType="s3",
      options=JsonOptions("""{"path": "s3://s3path"}"""),
      format="avro"
    ).writeDynamicFrame(dynamicFrame)
  }
}
```

------

## Avro 配置参考
<a name="aws-glue-programming-etl-format-avro-reference"></a>

您可以在 AWS Glue 库指定 `format="avro"` 的任何位置使用以下 `format_options` 值：
+ `version` – 指定要支持的 Apache Avro 读取器/写入器格式的版本。默认值为“1.7”。您可以指定 `format_options={"version": “1.8”}` 以启用 Avro 逻辑类型读取和写入。有关更多信息，请参阅 [Apache Avro 1.7.7 规范](https://avro.apache.org/docs/1.7.7/spec.html)和 [Apache Avro 1.8.2 规范](https://avro.apache.org/docs/1.8.2/spec.html)。

  Apache Avro 1.8 连接器支持以下逻辑类型转换：

对于读取器：此表显示 Avro 数据类型（逻辑类型和 Avro 基元类型）与 Avro 阅读器 1.7 和 1.8 的 AWS Glue `DynamicFrame` 数据类型之间的转换。


| Avro 数据类型：逻辑类型 | Avro 数据类型：Avro 基元类型 | GlueDynamicFrame 数据类型：Avro 读取器 1.7 | GlueDynamicFrame 数据类型：Avro 读取器 1.8 | 
| --- | --- | --- | --- | 
| 十进制 | bytes | BINARY | 十进制 | 
| 十进制 | 固定 | BINARY | 十进制 | 
| 日期 | 整数 | INT | 日期 | 
| 时间（毫秒） | 整数 | INT | INT | 
| 时间（微秒） | 长整数 | LONG | LONG | 
| 时间戳（毫秒） | 长整数 | LONG | Timestamp | 
| 时间戳（微秒） | 长整数 | LONG | LONG | 
| 持续时间（不是逻辑类型） | 固定为 12 | BINARY | BINARY | 

对于写入器：此表显示 Avro 写入器 1.7 和 1.8 在 AWS Glue `DynamicFrame` 数据类型与 Avro 数据类型之间的转换。


| AWS Glue `DynamicFrame` 数据类型 | Avro 数据类型：Avro 写入器 1.7 | Avro 数据类型：Avro 写入器 1.8 | 
| --- | --- | --- | 
| 十进制 | 字符串 | decimal | 
| 日期 | 字符串 | date | 
| Timestamp | 字符串 | timestamp-micros | 

## Avro Spark DataFrame 支持
<a name="aws-glueprogramming-etl-format-avro-dataframe-support"></a>

要使用 Spark DataFrame API 中的 Avro，您需要为相应的 Spark 版本安装 Spark Avro 插件。任务中可用的 Spark 版本取决于您的 AWS Glue 版本。有关 Spark 版本的更多信息，请参阅 [AWS Glue 版本](release-notes.md)。该插件由 Apache 维护，我们不提供具体的支持保证。

在 AWS Glue 2.0 中 – 使用 2.4.3 版本的 Spark Avro 插件。您可以在 Maven Central 上找到该 JAR，请参阅 [org.apache.spark:spark-avro\$12.12:2.4.3](https://search.maven.org/artifact/org.apache.spark/spark-avro_2.12/3.1.1/jar)。

在 AWS Glue 3.0 中 – 使用3.1.1 版本的 Spark Avro 插件。您可以在 Maven Central 上找到该 JAR，请参阅 [org.apache.spark:spark-avro\$12.12:3.1.1](https://search.maven.org/artifact/org.apache.spark/spark-avro_2.12/3.1.1/jar)。

要在 AWS Glue ETL 任务中加入额外的 JAR，请使用 `--extra-jars` 任务参数。有关任务参数的更多信息，请参阅 [在 AWS Glue 作业中使用作业参数](aws-glue-programming-etl-glue-arguments.md)。您也可以在 AWS 管理控制台 中配置此参数。