EMR Serverless 的元存储配置 - Amazon EMR

EMR Serverless 的元存储配置

Hive 元存储是一个集中位置,用于存储表的结构信息,包括架构、分区名称和数据类型。通过 EMR Serverless,可将表元数据保存在可以访问作业的元存储中。

对于 Hive 元存储,您有两个选项:

  • AWS Glue Data Catalog

  • 外部 Apache Hive 元存储

使用 AWS Glue Data Catalog 作为元存储

您可以将 Spark 和 Hive 作业配置为使用 AWS Glue Data Catalog 作为其元存储。如果需要持久元存储,或不同应用程序、服务或 AWS 账户 应用程序共享元存储,建议使用此配置。有关数据目录的更多信息,请参阅填充 AWS Glue Data Catalog。有关 AWS Glue 定价的信息,请参阅 AWS Glue 定价

您可以将 EMR Serverless 作业配置为在与应用程序相同的 AWS 账户 或不同的 AWS 账户 中使用 AWS Glue Data Catalog。

配置 AWS Glue Data Catalog

要配置数据目录,请选择要使用的 EMR Serverless 应用程序类型。

Spark

当您使用 EMR Studio 通过 EMR Serverless Spark 应用程序运行作业时,AWS Glue Data Catalog 是默认元存储。

使用 SDK 或 AWS CLI 时,您可以在作业运行的 sparkSubmit 参数中将 spark.hadoop.hive.metastore.client.factory.class 配置设置为 com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory。下面的示例显示了如何使用 AWS CLI 配置数据目录。

aws emr-serverless start-job-run \ --application-id application-id \ --execution-role-arn job-role-arn \ --job-driver '{ "sparkSubmit": { "entryPoint": "s3://amzn-s3-demo-bucket/code/pyspark/extreme_weather.py", "sparkSubmitParameters": "--conf spark.hadoop.hive.metastore.client.factory.class=com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory --conf spark.driver.cores=1 --conf spark.driver.memory=3g --conf spark.executor.cores=4 --conf spark.executor.memory=3g" } }'

或者,您可以在 Spark 代码中创建新 SparkSession 时设置此配置。

from pyspark.sql import SparkSession spark = ( SparkSession.builder.appName("SparkSQL") .config( "spark.hadoop.hive.metastore.client.factory.class", "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory", ) .enableHiveSupport() .getOrCreate() ) # we can query tables with SparkSQL spark.sql("SHOW TABLES").show() # we can also them with native Spark print(spark.catalog.listTables())
Hive

对于 EMR Serverless Hive 应用程序,数据目录是默认的元存储。也就是说,当您在 EMR Serverless Hive 应用程序上运行作业时,Hive 会将元存储信息记录在与您的应用程序相同的 AWS 账户 的数据目录中。您不需要虚拟私有云(VPC)即可将数据目录用作元存储。

要访问 Hive 元存储表,请添加设置 AWS Glue 的 IAM 权限中概述的所需 AWS Glue 策略。

配置 EMR Serverless 和 AWS Glue Data Catalog 的跨账户访问

要设置 EMR Serverless 的跨账户访问,必须先登录以下 AWS 账户:

  • AccountA:您在其中创建 EMR Serverless 应用程序的 AWS 账户。

  • AccountB:一个 AWS 账户,其中包含您希望 EMR Serverless 作业运行访问的 AWS Glue Data Catalog。

  1. 确保 AccountB 中的管理员或其他授权身份将资源策略附加到 AccountB 中的数据目录。此策略授予 AccountA 特定的跨账户权限,以便对 AccountB 目录中的资源执行操作。

    { "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Principal": { "AWS": [ "arn:aws:iam::accountA:role/job-runtime-role-A" ]}, "Action" : [ "glue:GetDatabase", "glue:CreateDatabase", "glue:GetDataBases", "glue:CreateTable", "glue:GetTable", "glue:UpdateTable", "glue:DeleteTable", "glue:GetTables", "glue:GetPartition", "glue:GetPartitions", "glue:CreatePartition", "glue:BatchCreatePartition", "glue:GetUserDefinedFunctions" ], "Resource": ["arn:aws:glue:region:AccountB:catalog"] } ] }
  2. 将 IAM 策略添加到 AccountA 中的 EMR Serverless 作业运行时角色,以便该角色可以访问 AccountB 中的数据目录资源。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "glue:GetDatabase", "glue:CreateDatabase", "glue:GetDataBases", "glue:CreateTable", "glue:GetTable", "glue:UpdateTable", "glue:DeleteTable", "glue:GetTables", "glue:GetPartition", "glue:GetPartitions", "glue:CreatePartition", "glue:BatchCreatePartition", "glue:GetUserDefinedFunctions" ], "Resource": ["arn:aws:glue:region:AccountB:catalog"] } ] }
  3. 启动作业运行。此步骤略有不同,具体取决于 AccountA 的 EMR Serverless 应用程序类型。

    Spark

    如以下示例所示,在 hive-site 分类中设置 spark.hadoop.hive.metastore.glue.catalogid 属性。将 AccountB-catalog-id 替换为 AccountB 中数据目录的 ID。

    aws emr-serverless start-job-run \ --application-id "application-id" \ --execution-role-arn "job-role-arn" \ --job-driver '{ "sparkSubmit": { "query": "s3://amzn-s3-demo-bucket/hive/scripts/create_table.sql", "parameters": "--hiveconf hive.exec.scratchdir=s3://amzn-s3-demo-bucket/hive/scratch --hiveconf hive.metastore.warehouse.dir=s3://amzn-s3-demo-bucket/hive/warehouse" } }' \ --configuration-overrides '{ "applicationConfiguration": [{ "classification": "hive-site", "properties": { "spark.hadoop.hive.metastore.glue.catalogid": "AccountB-catalog-id" } }] }'
    Hive

    如以下示例所示,在 hive-site 分类中设置 hive.metastore.glue.catalogid 属性。将 AccountB-catalog-id 替换为 AccountB 中数据目录的 ID。

    aws emr-serverless start-job-run \ --application-id "application-id" \ --execution-role-arn "job-role-arn" \ --job-driver '{ "hive": { "query": "s3://amzn-s3-demo-bucket/hive/scripts/create_table.sql", "parameters": "--hiveconf hive.exec.scratchdir=s3://amzn-s3-demo-bucket/hive/scratch --hiveconf hive.metastore.warehouse.dir=s3://amzn-s3-demo-bucket/hive/warehouse" } }' \ --configuration-overrides '{ "applicationConfiguration": [{ "classification": "hive-site", "properties": { "hive.metastore.glue.catalogid": "AccountB-catalog-id" } }] }'

使用 AWS Glue Data Catalog 时的注意事项

您可以在 Hive 脚本中添加具有 ADD JAR 的辅助 JAR。有关其他注意事项,请参阅使用 AWS Glue Data Catalog 时的注意事项

使用外部 Hive 元存储

您可以配置 EMR Serverless Spark 和 Hive 作业,使其连接到外部 Hive 元存储,如 Amazon Aurora 或 Amazon RDS for MySQL。本节介绍了如何设置 Amazon RDS Hive 元存储、配置 VPC 和配置 EMR Serverless 作业以使用外部元存储。

创建外部 Hive 元存储

  1. 按照创建 VPC 中的说明,创建具有私有子网的 Amazon Virtual Private Cloud(Amazon VPC)。

  2. 使用新的 Amazon VPC 和私有子网创建 EMR Serverless 应用程序。当您使用 VPC 配置 EMR Serverless 应用程序时,首先会为您指定的每个子网预置一个弹性网络接口。然后,将您指定的安全组附加到该网络接口。这样就可以对应用程序进行访问控制。有关如何设置 VPC 的更多详细信息,请参阅 为 EMR Serverless 应用程序配置 VPC 访问权限以连接数据

  3. 在 Amazon VPC 的私有子网中创建 MySQL 或 Aurora PostgreSQL 数据库。有关如何创建 Amazon RDS 数据库的信息,请参阅创建 Amazon RDS 数据库实例

  4. 按照修改 Amazon RDS 数据库实例中的步骤修改 MySQL 或 Aurora 数据库的安全组,允许来自 EMR Serverless 安全组的 JDBC 连接。为从其中一个 EMR Serverless 安全组到 RDS 安全组的入站流量添加规则。

    类型 协议 端口范围 来源

    所有 TCP

    TCP

    3306

    emr-serverless-security-group

配置 Spark 选项

使用 JDBC

要将 EMR Serverless Spark 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储,请使用 JDBC 连接。在作业运行的 spark-submit 参数中传递带有 --jarsmariadb-connector-java.jar

aws emr-serverless start-job-run \ --application-id "application-id" \ --execution-role-arn "job-role-arn" \ --job-driver '{ "sparkSubmit": { "entryPoint": "s3://amzn-s3-demo-bucket/scripts/spark-jdbc.py", "sparkSubmitParameters": "--jars s3://amzn-s3-demo-bucket/mariadb-connector-java.jar --conf spark.hadoop.javax.jdo.option.ConnectionDriverName=org.mariadb.jdbc.Driver --conf spark.hadoop.javax.jdo.option.ConnectionUserName=<connection-user-name> --conf spark.hadoop.javax.jdo.option.ConnectionPassword=<connection-password> --conf spark.hadoop.javax.jdo.option.ConnectionURL=<JDBC-Connection-string> --conf spark.driver.cores=2 --conf spark.executor.memory=10G --conf spark.driver.memory=6G --conf spark.executor.cores=4" } }' \ --configuration-overrides '{ "monitoringConfiguration": { "s3MonitoringConfiguration": { "logUri": "s3://amzn-s3-demo-bucket/spark/logs/" } } }'

以下代码示例是一个 Spark 入口点脚本,与 Amazon RDS 上的 Hive 元存储交互。

from os.path import expanduser, join, abspath from pyspark.sql import SparkSession from pyspark.sql import Row # warehouse_location points to the default location for managed databases and tables warehouse_location = abspath('spark-warehouse') spark = SparkSession \ .builder \ .config("spark.sql.warehouse.dir", warehouse_location) \ .enableHiveSupport() \ .getOrCreate() spark.sql("SHOW DATABASES").show() spark.sql("CREATE EXTERNAL TABLE `sampledb`.`sparknyctaxi`(`dispatching_base_num` string, `pickup_datetime` string, `dropoff_datetime` string, `pulocationid` bigint, `dolocationid` bigint, `sr_flag` bigint) STORED AS PARQUET LOCATION 's3://<s3 prefix>/nyctaxi_parquet/'") spark.sql("SELECT count(*) FROM sampledb.sparknyctaxi").show() spark.stop()

使用 thrift 服务

您可以将 EMR Serverless Hive 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储。为此,请在现有 Amazon EMR 集群的主节点上运行 thrift 服务器。如果您已经有一个 Amazon EMR 集群,其中包含用于简化 EMR Serverless 作业配置的 thrift 服务器,则此选项是理想之选。

aws emr-serverless start-job-run \ --application-id "application-id" \ --execution-role-arn "job-role-arn" \ --job-driver '{ "sparkSubmit": { "entryPoint": "s3://amzn-s3-demo-bucket/thriftscript.py", "sparkSubmitParameters": "--jars s3://amzn-s3-demo-bucket/mariadb-connector-java.jar --conf spark.driver.cores=2 --conf spark.executor.memory=10G --conf spark.driver.memory=6G --conf spark.executor.cores=4" } }' \ --configuration-overrides '{ "monitoringConfiguration": { "s3MonitoringConfiguration": { "logUri": "s3://amzn-s3-demo-bucket/spark/logs/" } } }'

以下代码示例是一个入口点脚本(thriftscript.py),使用 thrift 协议连接到 Hive 元存储。请注意,需要将 hive.metastore.uris 属性设置为从外部 Hive 元存储读取。

from os.path import expanduser, join, abspath from pyspark.sql import SparkSession from pyspark.sql import Row # warehouse_location points to the default location for managed databases and tables warehouse_location = abspath('spark-warehouse') spark = SparkSession \ .builder \ .config("spark.sql.warehouse.dir", warehouse_location) \ .config("hive.metastore.uris","thrift://thrift-server-host:thift-server-port") \ .enableHiveSupport() \ .getOrCreate() spark.sql("SHOW DATABASES").show() spark.sql("CREATE EXTERNAL TABLE sampledb.`sparknyctaxi`( `dispatching_base_num` string, `pickup_datetime` string, `dropoff_datetime` string, `pulocationid` bigint, `dolocationid` bigint, `sr_flag` bigint) STORED AS PARQUET LOCATION 's3://<s3 prefix>/nyctaxi_parquet/'") spark.sql("SELECT * FROM sampledb.sparknyctaxi").show() spark.stop()

配置 Hive 选项

使用 JDBC

如果要在 Amazon RDS MySQL 或 Amazon Aurora 实例上指定外部 Hive 数据库位置,可以覆盖默认的元存储配置。

注意

在 Hive 中,您可以同时对元存储表执行多次写入。如果在两个作业之间共享元存储信息,请确保不要同时写入同一个元存储表,除非写入同一元存储表的不同分区。

hive-site 分类中设置以下配置以激活外部 Hive 元存储。

{ "classification": "hive-site", "properties": { "hive.metastore.client.factory.class": "org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory", "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver", "javax.jdo.option.ConnectionURL": "jdbc:mysql://db-host:db-port/db-name", "javax.jdo.option.ConnectionUserName": "username", "javax.jdo.option.ConnectionPassword": "password" } }

使用 thrift 服务器

您可以将 EMR Serverless Hive 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储。为此,请在现有 Amazon EMR 集群的主节点上运行 thrift 服务器。如果您已经有一个运行 thrift 服务器的 Amazon EMR 集群,希望使用 EMR Serverless 作业配置,则此选项是理想之选。

hive-site 分类中设置以下配置,以便 EMR Serverless 可以访问远程 thrift 元存储。请注意,必须将 hive.metastore.uris 属性设置为从外部 Hive 元存储读取。

{ "classification": "hive-site", "properties": { "hive.metastore.client.factory.class": "org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory", "hive.metastore.uris": "thrift://thrift-server-host:thirft-server-port" } }

使用外部元存储时的注意事项

  • 您可以将与 MariaDB JDBC 兼容的数据库配置为元存储。这些数据库的示例包括 RDS for MariaDB、MySQL 和 Amazon Aurora。

  • 元存储不会自动初始化。如果元存储未使用适合 Hive 版本的架构初始化,请使用 Hive Schema Tool

  • EMR Serverless 不支持 Kerberos 身份验证。您不能将具有 Kerberos 身份验证的 thrift 元存储服务器与 EMR Serverless Spark 或 Hive 作业一起使用。