了解 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 数据库添加位置
登录 Amazon Web Services Management Console,然后打开 Amazon Glue 控制台,网址为:https://console.aws.amazon.com/glue/
。 -
在导航窗格中,选择 Databases(数据库)。
-
在数据库列表中,选择要编辑的数据库。
-
在数据库的详细信息页面上,选择 Edit(编辑)。
-
在 Update a database(更新数据库)页面上,在 Location(位置)处输入 Amazon S3 位置。
-
选择 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://amzn-s3-demo-bucket/'").
建议的解决方法 D – 如果您在创建表时指定了位置,但问题仍然出现,请确保您提供的 Amazon S3 路径包含尾部正斜杠。例如,以下命令会引发非法参数异常:
spark.sql("create table testTable (firstName STRING) location 's3://amzn-s3-demo-bucket'")
要更正此问题,请向该位置添加尾部斜杠(例如 's3://amzn-s3-demo-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 表元数据可以指向两个不同位置。当您尝试 INSERT
或 DROP TABLE
操作时,这可能会导致意外行为。
要重现该问题,步骤如下:
-
在 Athena for Spark 中,使用以下方法之一创建或保存 Hive 托管表:
-
SQL 语句,例如
CREATE TABLE $tableName
-
PySpark 命令,例如未在 Dataframe API 中指定
path
选项的df.write.mode("overwrite").saveAsTable($tableName)
。
此时,Amazon Glue 控制台可能会在 Amazon S3 中显示错误的表位置。
-
-
在 Athena for Spark 中,使用
DROP TABLE $table_name
语句删除您创建的表。 -
在运行
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