Athena for Spark 中的已知问题 - Amazon Athena
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Athena for Spark 中的已知问题

本页面记录了 Athena for Apache Spark 中的一些已知问题。

创建表时出现非法参数异常

尽管 Spark 不允许创建位置属性为空的数据库,但如果数据库是在 Spark 外部创建的,Amazon Glue 中数据库的 LOCATION 属性可能为空。

如果您创建表并指定 LOCATION 字段为空的 Amazon Glue 数据库,可能会出现以下异常:IllegalArgumentException: Cannot create a path from an empty string.(IllegalArgumentException:无法从空字符串创建路径。)

例如,如果 Amazon Glue 中的默认数据库 LOCATION 字段为空,以下命令会引发异常:

spark.sql("create table testTable (firstName STRING)")

建议的解决方法 A – 使用 Amazon Glue 向正在使用的数据库添加位置。

向 Amazon Glue 数据库添加位置
  1. 登录 Amazon Web Services Management Console,然后打开 Amazon Glue 控制台,网址为:https://console.aws.amazon.com/glue/

  2. 在导航窗格中,选择 Databases(数据库)。

  3. 在数据库列表中,选择要编辑的数据库。

  4. 在数据库的详细信息页面上,选择 Edit(编辑)。

  5. Update a database(更新数据库)页面上,在 Location(位置)处输入 Amazon S3 位置。

  6. 选择 Update Database(更新数据库)。

建议的解决方法 B – 使用其他 Amazon Glue 数据库,该数据库在 Amazon S3 中具有现有有效位置。例如,如果您有一个名为 dbWithLocation 的数据库,请使用命令 spark.sql("use dbWithLocation") 切换到该数据库。

建议的解决方法 C – 使用 Spark SQL 创建表时,为 location 指定一个值,如下例所示。

spark.sql("create table testTable (firstName STRING) location 's3://DOC-EXAMPLE-BUCKET/'").

建议的解决方法 D – 如果您在创建表时指定了位置,但问题仍然出现,请确保您提供的 Amazon S3 路径包含尾部正斜杠。例如,以下命令会引发非法参数异常:

spark.sql("create table testTable (firstName STRING) location 's3://DOC-EXAMPLE-BUCKET'")

要更正此问题,请向该位置添加尾部斜杠(例如 's3:// DOC-EXAMPLE-BUCKET/')。

在工作组位置创建的数据库

如果您使用 spark.sql('create database db') 之类的命令创建数据库,但不指定数据库的位置,Athena 会在您的工作组位置创建一个子目录,并将该位置用于新创建的数据库。

Amazon Glue 默认数据库中 Hive 托管的表问题

如果 Amazon Glue 中默认数据库的 Location 属性不为空并指定 Amazon S3 中的有效位置,并且您使用 Athena for Spark 在 Amazon Glue 默认数据库中创建 Hive 托管表,则数据将写入在 Athena Spark 工作组中指定的 Amazon S3 位置,而不是 Amazon Glue 数据库指定的位置。

是否会出现此问题取决于 Apache Hive 如何处理其默认数据库。Apache Hive 在 Hive 仓库根位置中创建表数据,该位置可能与实际的默认数据库位置不同。

当您使用 Athena for Spark 在 Amazon Glue 中的默认数据库下创建 Hive 托管表时,Amazon Glue 表元数据可以指向两个不同位置。当您尝试 INSERTDROP TABLE 操作时,这可能会导致意外行为。

要重现该问题,步骤如下:

  1. 在 Athena for Spark 中,使用以下方法之一创建或保存 Hive 托管表:

    • SQL 语句,例如 CREATE TABLE $tableName

    • PySpark 命令,例如未在 Dataframe API 中指定 path 选项的 df.write.mode("overwrite").saveAsTable($tableName)

    此时,Amazon Glue 控制台可能会在 Amazon S3 中显示错误的表位置。

  2. 在 Athena for Spark 中,使用 DROP TABLE $table_name 语句删除您创建的表。

  3. 在运行 DROP TABLE 语句后,您会注意到 Amazon S3 中的底层文件仍然存在。

要解决该问题,可以执行下列操作之一:

解决方案 A - 创建 Hive 托管表时使用其他 Amazon Glue 数据库。

解决方案 B - 为 Amazon Glue 中的默认数据库指定一个空位置。然后,在默认数据库中创建托管表。

Athena for Spark 和 Athena SQL 之间的 CSV 和 JSON 文件格式不兼容

由于开源 Spark 存在的已知问题,在 Athena for Spark 中根据 CSV 或 JSON 数据创建表时,可能无法从 Athena SQL 中读取该表,反之亦然。

例如,您可能使用以下方法之一在 Athena for Spark 中创建表:

  • 使用下面的 USING csv 语法:

    spark.sql('''CREATE EXTERNAL TABLE $tableName ( $colName1 $colType1, $colName2 $colType2, $colName3 $colType3) USING csv PARTITIONED BY ($colName1) LOCATION $s3_location''')
  • 使用以下 DataFrame API 语法:

    df.write.format('csv').saveAsTable($table_name)

由于开源 Spark 存在的已知问题,从 Athena SQL 对生成的表进行查询可能失败。

建议的解决方案 - 尝试在 Athena for Spark 中使用 Apache Hive 语法创建表。有关更多信息,请参阅 Apache Spark 文档中的 CREATE HIVEFORMAT TABLE